Skip to content

microgrid.cli.dataset

A dataset: a directory of the library's series (dataset/1), so every command runs without the plant it came from.

The format, dataset/1, is the library's own terms, not any integration's:

  • manifest.json: {"format": "dataset/1", "entries": {name: {"file": ..., "kind": ..., "forecasts": bool}}}. An entry's kind is how its values read: number, bool, price ({"import": ..., "export": ...}, per kWh) or quantiles ({"0.1": ..., "0.5": ..., "0.9": ...}, or "0.5" alone).
  • A series file (forecasts false): {"unit": ..., "known_until": ..., "samples": [[at, value], ...]}, each value held until the next, null for none.
  • A forecasts file (forecasts true): {"unit": ..., "known_until": ..., "issues": [{"received_at": ..., "issued_at": ..., "source": ..., "intervals": [[start, end, value], ...]}, ...]}, each issue as the client received it; {"received_at": ..., "issue": null} where the source answered nothing.

Times are ISO 8601 with an offset (read as UTC). Units are the source's, stated in each file: microgrid.cli.inputs.inputs converts them to the engine's (microgrid.engine.units) and refuses one it cannot, so a value in another unit is never used as the engine's.

The names a dataset gives its entries are conventional. microgrid.cli.inputs.inputs reads the engine's inputs: PRICES, PV_FORECAST (or pv_forecast.<array>, one per array, for a plant that takes PV per array), LOAD_FORECAST, DC_LOAD_FORECAST, SOC and BATTERY_FIRST. The rest are what was metered, for the commands that score against it: the plant's meters by the plant's names (pv, grid, battery, dc_load), HOUSE, the house meter, and HEARTBEAT, a series whose samples prove the telemetry path alive. A name is letters, digits, _, - and .: each entry's file stays in the directory.

FORMAT module-attribute

FORMAT: Final = 'dataset/1'

MANIFEST module-attribute

MANIFEST: Final = 'manifest.json'

PRICES module-attribute

PRICES: Final = 'prices'

PV_FORECAST module-attribute

PV_FORECAST: Final = 'pv_forecast'

LOAD_FORECAST module-attribute

LOAD_FORECAST: Final = 'load_forecast'

DC_LOAD_FORECAST module-attribute

DC_LOAD_FORECAST: Final = 'dc_load_forecast'

SOC module-attribute

SOC: Final = 'soc'

BATTERY_FIRST module-attribute

BATTERY_FIRST: Final = 'battery_first'

HOUSE module-attribute

HOUSE: Final = 'house'

HEARTBEAT module-attribute

HEARTBEAT: Final = 'heartbeat'

IMPORT_PRICE module-attribute

IMPORT_PRICE: Final = 'import_price'

The import and export prices in force, as recorded (TariffKit's price sensors' history): what the battery's lots were charged and valued at (history.read_recorded).

EXPORT_PRICE module-attribute

EXPORT_PRICE: Final = 'export_price'

INVERTER module-attribute

INVERTER: Final = 'inverter'

The battery inverter's AC power, > 0 out: for fitting the battery's conversion.

DOMAIN module-attribute

DOMAIN: Final = 'dataset'

A dataset's entries as entity IDs (dataset.<name>), so bindings name them as they name any recorder's (DatasetHistory, history.Bindings).

Kind

Kind = Literal['number', 'bool', 'price', 'quantiles']

Value

Value = float | bool | Price | Quantiles

DatasetError

Bases: ValueError

A dataset that cannot be read: the message names the file and what is wrong.

Entry dataclass

Entry(
    kind: Kind, series: Series[Any], forecasts: bool = False
)

One series or series of forecasts of a dataset, as written or read.

kind instance-attribute

kind: Kind

series instance-attribute

series: Series[Any]

A series of values, or of forecasts as received (forecasts), the values of the entry's kind (Series is invariant, so any series of them).

forecasts class-attribute instance-attribute

forecasts: bool = False

Dataset dataclass

Dataset(
    entries: Mapping[str, Entry],
    limits: Limits | None = None,
)

A dataset's entries by name, and how its record's silences are judged where the manifest says (limits; None: the command's flags, else the defaults).

entries instance-attribute

entries: Mapping[str, Entry]

limits class-attribute instance-attribute

limits: Limits | None = None

series

series(name: str) -> Series[Value] | None

A series of values by name; None where the dataset has none.

forecasts

forecasts(name: str) -> Series[Forecast[Value]] | None

A series of forecasts by name; None where the dataset has none.

DatasetHistory dataclass

DatasetHistory(dataset: Dataset)

A dataset read as recorded history (History), each entity dataset.<name> its entry name: the ledger, the ground truth and the battery's fit run on a dataset as on any recorder.

dataset instance-attribute

dataset: Dataset

power_series async

power_series(
    entity_id: str,
    start: datetime,
    end: datetime,
    *,
    carry_in: timedelta,
    chunk: timedelta | None = None,
) -> Series[float]

Power in kW, converted from the entry's unit.

numeric_series async

numeric_series(
    entity_id: str,
    start: datetime,
    end: datetime,
    *,
    carry_in: timedelta,
    chunk: timedelta | None = None,
) -> Series[float]

Any numeric entry's values, the unit not carried (History.numeric_series).

sample_times async

sample_times(
    entity_id: str,
    start: datetime,
    end: datetime,
    *,
    carry_in: timedelta,
    chunk: timedelta | None = None,
) -> tuple[datetime, ...]

When the entry's samples arrived (a liveness entry's).

read_dataset

read_dataset(directory: Path) -> Dataset

The dataset in directory; raises DatasetError naming what is wrong.

write_dataset

write_dataset(
    directory: Path,
    entries: Mapping[str, Entry],
    *,
    limits: Limits | None = None,
) -> None

Write entries as a dataset in directory (made if it does not exist): one file per entry, series/<name>.json or forecasts/<name>.json, and the record's limits where given.