Skip to content

microgrid.cli.sources.config

sources/1: the file that says where each input comes from.

.. code-block:: toml

schema = "sources/1"
plant = "plant.toml"            # plant/2, beside this file
engine = "engine.toml"          # engine/2; optional (the library's defaults)

[home_assistant]                # a connection, for the sources that read it
url = "http://homeassistant.local:8123"
token_env = "MICROGRID_HA_TOKEN"  # the variable holding the token (this default)

[prices]
from = "tariffkit"              # or "entity"

[pv_forecast]
from = "solcast"                # or "entity"
entities = ["sensor.solcast_pv_forecast_forecast_today", "..."]
last_polled = "sensor.solcast_pv_forecast_api_last_polled"

[load_forecast]
from = "emhass"                 # or "predbat", "entity"

[measured]
from = "home_assistant"
soc = "sensor.battery_soc"
house = "sensor.house_load"
[measured.meters]               # the plant's meters (plant/2), by name
pv = "sensor.pv_power"
grid = "sensor.grid_power"
battery = "sensor.battery_power"

Every section but plant is optional: an input with no source is not read, and a valuation that needs it names it as a cause. No entity has a default (they are each site's own), except where a tool publishes under a fixed name (EMHASS's and Predbat's entities, which a section may rename). Paths are relative to this file. The token is never read from the file.

SCHEMA module-attribute

SCHEMA: Final = 'sources/1'

HA_TOKEN_ENV module-attribute

HA_TOKEN_ENV: Final = 'MICROGRID_HA_TOKEN'

The environment variable a Home Assistant token is read from, unless token_env names another.

PriceSource

PriceSource = TariffKit | EntityForecast

PvSource

PvSource = Solcast | EntityForecast

LoadSource

LoadSource = Emhass | Predbat | EntityForecast

SourcesConfigError

SourcesConfigError(errors: list[str])

Bases: ValueError

A sources/1 file that cannot be used; errors names each problem.

errors instance-attribute

errors = tuple(errors)

HomeAssistant dataclass

HomeAssistant(url: str, token_env: str = HA_TOKEN_ENV)

A Home Assistant instance, read over its REST API.

url instance-attribute

url: str

token_env class-attribute instance-attribute

token_env: str = HA_TOKEN_ENV

TariffKit dataclass

TariffKit(config_entry: str | None = None)

Prices from TariffKit's Home Assistant integration (its get_rates service).

config_entry class-attribute instance-attribute

config_entry: str | None = None

The integration's config entry; None: the one loaded.

Solcast dataclass

Solcast(entities: tuple[str, ...], last_polled: str)

A PV forecast from the Solcast integration's daily forecast entities.

entities instance-attribute

entities: tuple[str, ...]

last_polled instance-attribute

last_polled: str

The entity holding the last successful poll: the forecast's age.

Emhass dataclass

Emhass(
    entity: str = "sensor.p_load_forecast",
    attribute: str = "forecasts",
    value_key: str = "p_load_forecast",
    period: timedelta = timedelta(minutes=30),
)

A load forecast EMHASS publishes: an entity whose attribute lists {date, value} rows, the mean power over period from each date.

entity class-attribute instance-attribute

entity: str = 'sensor.p_load_forecast'

attribute class-attribute instance-attribute

attribute: str = 'forecasts'

value_key class-attribute instance-attribute

value_key: str = 'p_load_forecast'

period class-attribute instance-attribute

period: timedelta = timedelta(minutes=30)

Predbat dataclass

Predbat(
    entity: str = "predbat.load_energy_predicted",
    attribute: str = "results",
    step: timedelta = timedelta(minutes=5),
)

A load forecast Predbat publishes: today's predicted energy, cumulative from local midnight, by time (results), in kWh. It reaches midnight: a valuation's horizon ends there (not horizon_cut, which is a gap with forecast after it).

entity class-attribute instance-attribute

entity: str = 'predbat.load_energy_predicted'

attribute class-attribute instance-attribute

attribute: str = 'results'

step class-attribute instance-attribute

step: timedelta = timedelta(minutes=5)

Each cumulative value includes the step starting at its time.

EntityForecast dataclass

EntityForecast(
    entity: str,
    attribute: str,
    start_key: str = "start",
    end_key: str | None = "end",
    period: timedelta | None = None,
    keys: Mapping[str, str] = dict(),
    unit: str | None = None,
)

Any entity whose attribute holds a forecast: a list of rows (objects), each with a start time, an end time or a fixed period, and its values under keys.

entity instance-attribute

entity: str

attribute instance-attribute

attribute: str

start_key class-attribute instance-attribute

start_key: str = 'start'

The row's start time key, and its end (None: period from the start).

end_key class-attribute instance-attribute

end_key: str | None = 'end'

period class-attribute instance-attribute

period: timedelta | None = None

keys class-attribute instance-attribute

keys: Mapping[str, str] = field(default_factory=dict)

The values' keys: import/export for prices; value, or p10/p50/ p90, for PV; value for a load.

unit class-attribute instance-attribute

unit: str | None = None

The values' unit (power: W, kW; prices: per kWh or per MWh, any currency); None: the entity's unit_of_measurement.

Measured dataclass

Measured(
    soc: str | None = None,
    soc_unit: str = "%",
    meters: Mapping[str, str] = dict(),
    house: str | None = None,
    dispatch: str | None = None,
    modelled_modes: tuple[str, ...] = (),
    dispatch_as_modelled: bool | None = None,
    heartbeat: str | None = None,
    import_price: str | None = None,
    export_price: str | None = None,
    inverter: str | None = None,
)

What is measured, read from Home Assistant: the SOC, the plant's meters by the plant's names, the house meter, and whether the plant runs the dispatch its model describes.

soc class-attribute instance-attribute

soc: str | None = None

soc_unit class-attribute instance-attribute

soc_unit: str = '%'

The SOC's unit where the entity states none (%; empty: a fraction).

meters class-attribute instance-attribute

meters: Mapping[str, str] = field(default_factory=dict)

house class-attribute instance-attribute

house: str | None = None

dispatch class-attribute instance-attribute

dispatch: str | None = None

The entity whose state is the plant's mode, and the modes that run the modelled dispatch; or dispatch_as_modelled true or false, without an entity.

modelled_modes class-attribute instance-attribute

modelled_modes: tuple[str, ...] = ()

dispatch_as_modelled class-attribute instance-attribute

dispatch_as_modelled: bool | None = None

heartbeat class-attribute instance-attribute

heartbeat: str | None = None

A series whose samples prove the readings were flowing (for fetch): any meter that reports every few seconds. None: the first meter's own samples.

import_price class-attribute instance-attribute

import_price: str | None = None

The import and export prices in force, as recorded (for fetch: the ledger).

export_price class-attribute instance-attribute

export_price: str | None = None

inverter class-attribute instance-attribute

inverter: str | None = None

The battery inverter's AC power, > 0 out (for fetch: fit-battery).

Sources dataclass

Sources(
    path: Path,
    plant: Path,
    engine: Path | None = None,
    home_assistant: HomeAssistant | None = None,
    prices: PriceSource | None = None,
    pv_forecast: PvSource | None = None,
    load_forecast: LoadSource | None = None,
    measured: Measured | None = None,
)

A sources/1 file, read.

path instance-attribute

path: Path

plant instance-attribute

plant: Path

engine class-attribute instance-attribute

engine: Path | None = None

home_assistant class-attribute instance-attribute

home_assistant: HomeAssistant | None = None

prices class-attribute instance-attribute

prices: PriceSource | None = None

pv_forecast class-attribute instance-attribute

pv_forecast: PvSource | None = None

load_forecast class-attribute instance-attribute

load_forecast: LoadSource | None = None

measured class-attribute instance-attribute

measured: Measured | None = None

uses_home_assistant

uses_home_assistant() -> bool

Whether any section reads Home Assistant.

read_sources

read_sources(path: Path) -> Sources

The sources/1 file at path. Raises SourcesConfigError naming every problem.