As announced in the Important Update: Evolving Our Data Platform for a Scalable Future post, starting September 22nd we will begin rolling out the new measurement processing to all HEMS systems. We are starting with Battery Measurements. In preparation for that switch, we have prepared the following technical overview.
Current situation
Currently, assets connected to a gridBox provide raw measurements at ~ 2-second intervals. These measurements can be retrieved using the Applianceās Raw Measurements API.
This endpoint is deprecated as transferring data that fine grained is inefficient for little benefit.
New Measurement Processing
We are introducing a new measurement processing, for greater scalability and efficiency. By optimizing the data granularity for cloud communication from 2-second to 30-second intervals, we reduce the amount of data sent to the cloud.
This comes with the following changes and improvements.
Flexible granularity
As announced, we will support a āgranularity fine-tuned for use-cases and flexible for testing and debugging purposesā. To achieve this, we needed a new measurement specification to support different intervals, example 2-second to 30-second intervals.
The new measurement specification:
- includes time metadata
- for a sampled measurement, represents the assetās state at a specific point in time
- for an aggregated measurement, represents the assetās state over a specific time interval.
- to simplify the specs, all number fields are now floats.
API
We have developed a new List Asset Measurements API, that is designed to handle measurements of different granularity (sampled vs aggregated).
The API is currently in draft mode, feedback is welcome.
Improvements compared to the existing API
The following improvements have been made to the new API specification, vs the existing one:
- assets are now linked to the system, not the gateway
- to cater to systems without physical gateways
- to allow for virtual or multiple gateways in the future, and because they are functionally unrelated to gateways
- battery measurements are returned, not inverter measurements, which aligns with the actual raw data
Sampled Measurements
In Phase 1, starting September 22nd, we will begin shifting gridBoxes to the new measurement processing, while keeping the granularity at 2-second intervals.
Sampled measurements are raw measurements, with no aggregation applied to them. The timestamp is unmodified.
{
"type": "BATTERY",
"measurements": [
{
"capacity": 6400,
"stateOfCharge": 10,
"chargePower": 0,
"dischargePower": 0,
"measuredAt": "2025-08-29T08:30:00Z"
},
{
"capacity": 6400,
"stateOfCharge": 10,
"chargePower": 0,
"dischargePower": 0,
"measuredAt": "2025-08-29T08:30:02Z"
},
{
"capacity": 6400,
"stateOfCharge": 10,
"chargePower": 0,
"dischargePower": 0,
"measuredAt": "2025-08-29T08:30:04Z"
}
]
}
Aggregated (Downsampled) Measurements
In Phase 2, the default granularity will change from 2-second to 30-second intervals. This is done by downsampling on the gridBox. Raw measurements are cached for 30s, downsampled, then sent to the cloud.
This does not affect measurements on the gridBox or the EMS.
When a measurement has been aggregated, it contains the interval. For example, when aggregated over 30-seconds, it will look like this:
"measuredFrom": "2025-09-05T18:00:00Z",
"measuredTo": "2025-09-05T18:00:30Z",
The downsampling of raw measurements is done on a field by field basis, and could be the min, max, last or average value over the interval. Averages are calculated using time-weighted-average.
Hereās an example set of aggregated measurements:
{
"type": "BATTERY",
"measurements": [
{
"activePower": 0,
"capacity": 6400,
"chargePower": 0,
"dischargePower": 0,
"measuredFrom": "2025-09-09T18:00:00Z",
"measuredTo": "2025-09-05T18:00:29Z",
"stateOfCharge": 99
},
{
"activePower": 0,
"capacity": 6400.000000000001,
"chargePower": 0,
"dischargePower": 0,
"measuredFrom": "2025-09-05T18:00:29Z",
"measuredTo": "2025-09-05T18:00:59Z",
"stateOfCharge": 99.00000000000001
},
{
"activePower": 0,
"capacity": 6400.000000000002,
"chargePower": 0,
"dischargePower": 0,
"measuredFrom": "2025-09-05T18:00:59Z",
"measuredTo": "2025-09-05T18:01:29Z",
"stateOfCharge": 99
},
{
"activePower": 0,
"capacity": 6399.999999999999,
"chargePower": 0,
"dischargePower": 0,
"measuredFrom": "2025-09-05T18:01:29Z",
"measuredTo": "2025-09-05T18:01:59Z",
"stateOfCharge": 99
},
{
"activePower": 0,
"capacity": 6400,
"chargePower": 0,
"dischargePower": 0,
"measuredFrom": "2025-09-05T18:02:00Z",
"measuredTo": "2025-09-05T18:02:29Z",
"stateOfCharge": 98.99999999999999
}
]
}
Existing Applianceās Raw Measurements API
The existing List Applianceās Raw Measurements API will continue to function with the new measurement types, with some adjustments
The API will have to convert the new measurements to fit the existing format.
- the
measuredAtfield will correspond to- the
measuredAtof a sampled measurement - the
measuredToof an aggregated measurement
- the
- due to the float ā integer conversion, some precision will be lost
API response with 2-second interval
[
{
"battery": {
"capacity": 6400,
"measuredAt": "2025-09-10T13:29:50Z",
"presentCharge": 0,
"presentDischarge": 0,
"stateOfCharge": 99
},
"measuredAt": "2025-09-10T13:29:50Z"
},
{
"battery": {
"capacity": 6400,
"measuredAt": "2025-09-10T13:29:52Z",
"presentCharge": 0,
"presentDischarge": 0,
"stateOfCharge": 99
},
"measuredAt": "2025-09-10T13:29:52Z"
},
{
"battery": {
"capacity": 6400,
"measuredAt": "2025-09-10T13:29:54Z",
"presentCharge": 0,
"presentDischarge": 0,
"stateOfCharge": 99
},
"measuredAt": "2025-09-10T13:29:54Z"
},
{
"battery": {
"capacity": 6400,
"measuredAt": "2025-09-10T13:29:56Z",
"presentCharge": 0,
"presentDischarge": 0,
"stateOfCharge": 99
},
"measuredAt": "2025-09-10T13:29:56Z"
}
]
API response with 30-second interval
[
{
"battery": {
"capacity": 6399,
"measuredAt": "2025-09-10T13:30:29Z",
"presentCharge": 0,
"presentDischarge": 0,
"stateOfCharge": 98
},
"measuredAt": "2025-09-10T13:30:29Z"
},
{
"battery": {
"capacity": 6400,
"measuredAt": "2025-09-10T13:30:59Z",
"presentCharge": 0,
"presentDischarge": 0,
"stateOfCharge": 99
},
"measuredAt": "2025-09-10T13:30:59Z"
},
{
"battery": {
"capacity": 6400,
"measuredAt": "2025-09-10T13:31:29Z",
"presentCharge": 0,
"presentDischarge": 0,
"stateOfCharge": 99
},
"measuredAt": "2025-09-10T13:31:29Z"
},
{
"battery": {
"capacity": 6400,
"measuredAt": "2025-09-10T13:31:59Z",
"presentCharge": 0,
"presentDischarge": 0,
"stateOfCharge": 98
},
"measuredAt": "2025-09-10T13:31:59Z"
}
]
Migration plan
There is no urgency to migrate right away. It will take some months before all assets are migrated to the new API. In the meantime, the existing API will continue to work (even after migration). The existing API will be deprecated sometime in 2026.
However, to take full advantage of the new measurement data, you should migrate to the new APIs.
Future Plans
In Phase 3, we will extend the functionality to all asset types.