microgrid.cli.offline¶
The library run on a dataset: the setup from the dataset's configuration files, one
valuation at a moment, and the live value over a span, each read from the dataset as a
client would have had it then; and the dataset's bindings, for the commands that read
what its meters recorded. Everything is on the engine's slot
(EngineConfig.slot, the dataset's engine.toml).
TELEMETRY
module-attribute
¶
A client's own cause, beside the engine's: the heartbeat says the telemetry path was silent, so nothing measured can be vouched for.
LOTS_RUN_IN
module-attribute
¶
How far back microgrid now runs the ledger for the battery's lots: two days drew
down what the battery held before (energy of unknown origin) at every slot of a
16-day replay on one home's plant. A battery
held full for longer keeps some of it.
Setup
dataclass
¶
read_plant
¶
The plant's file (plant/2, TOML) at path; its timezone names the zone.
Raises PlantConfigError naming each problem.
load_setup
¶
load_setup(
data: Path,
plant: Path | None = None,
engine: Path | None = None,
*,
beside: bool = True,
) -> Setup
The plant from plant (default: the dataset's plant.toml), the engine from
engine (default: the dataset's engine.toml where beside, else the
library's defaults).
engine_inputs
¶
engine_inputs(
setup: Setup,
read: Inputs,
at: datetime,
lots: Series[Lots] | None = None,
) -> Inputs
The engine's inputs at at from a dataset's (inputs.inputs), with the
battery's lots (dataset_lots). A plant with DC-bus loads and no forecast
of them takes a forecast of 0, labelled so (inputs.no_dc_forecast).
client_causes
¶
What the command assumed in valuing dataset, named beside the engine's causes
(never in place of them): a plant with DC-bus loads and no forecast of them valued on
0 kW (ASSUMED_DC_LOAD).
limits_of
¶
How the dataset's record is judged: given (a command's flags), else the
dataset's own (its manifest's limits), else the defaults.
with_recorded_prices
¶
dataset with the prices in force as recorded series (import_price,
export_price), derived from its price forecasts where it records none
(inputs.prices_in_force): a dataset need not carry the prices twice. Recorded ones
are per kWh, all in one currency (inputs.recorded_prices).
dataset_lots_async
async
¶
dataset_lots_async(
setup: Setup,
dataset: Dataset,
*,
limits: Limits | None = None,
) -> Series[Lots] | None
The battery's lots over the dataset, after each slot (the ledger over what its
meters recorded, history.read_recorded, on the engine's slot): what a valuation at
a moment reads as the energy the battery holds then. The prices are the recorded ones,
else those its forecasts put in force (with_recorded_prices); the path is
alive within the heartbeat's limit where it has one (limits: limits_of),
else wherever each series is known. None where the dataset cannot say (no battery, no
recorded meters or SOC, or no prices): the engine then values all the battery holds as
of unknown origin, at the import, and names battery_lots; lots_missing
says why. The ledger starts at the dataset's first whole slot, all it holds then of
unknown origin.
lots_missing
¶
Why dataset_lots gives none for a plant with a battery; None where it gives
lots, or the plant has no battery.
lots_or_why
async
¶
lots_or_why(
setup: Setup,
dataset: Dataset,
*,
limits: Limits | None = None,
) -> tuple[Series[Lots] | None, str | None]
dataset_lots_async's lots, and where it gives none for a plant with a
battery, why (else None).
dataset_lots
¶
dataset_lots(
setup: Setup,
dataset: Dataset,
*,
limits: Limits | None = None,
) -> Series[Lots] | None
dataset_lots_async, for a caller outside an event loop.
value
¶
value(
setup: Setup,
dataset: Dataset,
at: datetime,
*,
limits: Limits | None = None,
) -> Valuation
The valuation at at from what the dataset says was received by then
(unpriced without a price for the slot under way), the battery's lots from the
dataset's meters (dataset_lots).
value_with
¶
value with the battery's lots given (read once for many valuations).
live
¶
live(
setup: Setup,
dataset: Dataset,
start: datetime,
end: datetime,
*,
every: timedelta,
issue_every: timedelta,
valid_for: timedelta,
limits: Limits | None = None,
) -> Iterator[tuple[datetime, LiveValue]]
The live value every every in [start, end), valued again at the first
reading in each issue_every from start (each valuation valid for
valid_for), as a client running the library would have had it. A valuation that
comes to nothing (unpriced) leaves the last one in place, as the service keeps its
last issue (past its valid_until, the engine names issue).
dataset_bindings
¶
The dataset's entries as the record the commands read (dataset.<name>, read
by DatasetHistory), for its plant (setup), its
silences judged by limits (limits_of). Its heartbeat where it has one
(else each series is trusted as far as it is known), its house meter and its
inverter's AC meter where it has them.