Readonlyopening: Record<string, HistoryOpening>The state at the start of the range, per entity id. Throws, saying how to get it, before the response has arrived, and says the request failed after one that did. Not enumerable, so spreading or logging the result is safe.
An opening with degraded: true is incomplete: the server could not look
far enough back for this response (degradedReason says why), so a field
it holds may be missing. Ask again in a minute for the full opening.
Make the request now, if it has not been made, and resolve to this object.
What HistoryApi.changeRows returns: the rows, and the state before them.
It is the async generator it always was.
for awaityields the same{ entityId, row }entries, and each row is the entity's complete live data from itstimeuntil the next row's.openingis the one thing the rows cannot tell you: the state in force at the START of the range, before the first change. Without it, the stretch between midnight and an entity's first change has no known status. On a night a ride runs past midnight that is real operating time, and a day rebuilt from the rows alone disagrees with the daily summary. It has an entry for every entity in the response, including one that did not change at all that day.Nothing is requested until the result is first used, as before. A getter cannot await, so
openingis readable once the response has arrived: after the first step of iteration, or straight away withconst changes = await history.changeRows(query).load(). Either way it is one request.