exerpy.schema¶
Formal schema and validation of the JSON model that ExerPy’s analyses read.
The JSON document fed into exerpy.ExergyAnalysis.from_json() (and produced by
the TESPy, Aspen and EBSILON parsers) is described here as msgspec structs.
The schema covers only the fields ExerPy reads. The keys of each component type are
declared next to the code that reads them, as the Input struct nested in the
component class (see exerpy.components.component.Component); this module
collects them from the component registry, so custom components are covered too. The
exports also carry what the simulators report besides (efficiencies, units, fluid ids,
results of an earlier analysis, …); ExerPy ignores those, and so does the validation.
Each field below notes where ExerPy uses it.
Validation happens in two steps, which can also be run on their own:
Structure (
check_structure()), on the input as it is written. While decoding,msgspecchecks the required keys, the types and thekindtag of each connection. On the decoded structs follow the rules that span several fields or sections, e.g. that each component type is registered, that no two streams enter the same inlet of a component, thatsplit_physical_exergyhas thee_T/e_Mvalues it needs, or that each unit given ("T_unit": "degC") is known and of the right kind. A value without a unit is in SI.Values (
check_values()): each value lies in its reasonable range, e.g. positive temperatures and pressures or mass fractions between 0 and 1. The ranges are theLimitof the types and hold in SI units.
The validation does not convert units. Before an analysis, ExerPy converts the values
with exerpy.units.to_SI() between the two steps.
The problems of a step are collected and reported together. The values are checked once the structure is valid.
Example
>>> from exerpy.schema import validate
>>> model = validate(open("example.json", "rb").read())
>>> model.connections["1"].m
637.86...
The JSON Schema of the format is returned by json_schema().
- class exerpy.schema.AmbientConditions(*, Tamb: Annotated[float, msgspec.Meta(description='Absolute temperature, in K unless a unit is given'), Limit(gt=0, ge=None, le=None)] | UnsetType = UNSET, pamb: Annotated[float, msgspec.Meta(description='Absolute pressure, in Pa unless a unit is given'), Limit(gt=0, ge=None, le=None)] | UnsetType = UNSET)[source]¶
Bases:
StructDead state of the analysis. Values may instead be passed to
from_json.
- class exerpy.schema.ExerpyInput(*, components: dict[str, dict[str, ~exerpy.components.component.Component.Input]], connections: dict[str, ~exerpy.schema.MaterialConnection | ~exerpy.schema.PowerConnection | ~exerpy.schema.HeatConnection | ~exerpy.schema.OtherConnection], ambient_conditions: ~exerpy.schema.AmbientConditions, settings: ~exerpy.schema.Settings = <factory>)[source]¶
Bases:
StructThe complete input document of an exergy analysis.
- class exerpy.schema.HeatConnection(energy_flow: float | None | UnsetType = UNSET, *, source_component: str | None, target_component: str | None, source_connector: Annotated[int, msgspec.Meta(ge=0, description='0-based port index on the component')] | None = None, target_connector: Annotated[int, msgspec.Meta(ge=0, description='0-based port index on the component')] | None = None, source_component_type: int | str | None | UnsetType = UNSET)[source]¶
Bases:
_ConnectionBaseHeat, in W. Its exergy is derived from the attached component.
- exception exerpy.schema.InputValidationError(issues: list[Issue])[source]¶
Bases:
ValueErrorRaised when the input fails validation.
issuesholds every finding.
- class exerpy.schema.Issue(severity: Literal['error', 'warning'], path: str, message: str)[source]¶
Bases:
StructOne validation finding, located by a JSONPath-like
path.
- class exerpy.schema.MaterialConnection(m: Annotated[float, msgspec.Meta(description='Mass flow, in kg/s unless a unit is given'), Limit(gt=None, ge=0, le=None)], T: Annotated[float, msgspec.Meta(description='Absolute temperature, in K unless a unit is given'), Limit(gt=0, ge=None, le=None)], e_PH: Annotated[float, msgspec.Meta(description='Specific exergy, in J/kg unless a unit is given')], h: Annotated[float, msgspec.Meta(description='Specific enthalpy, in J/kg unless a unit is given')], p: Annotated[float, msgspec.Meta(description='Absolute pressure, in Pa unless a unit is given'), Limit(gt=0, ge=None, le=None)], e_T: Annotated[float, msgspec.Meta(description='Specific exergy, in J/kg unless a unit is given')] | None | UnsetType = UNSET, e_M: Annotated[float, msgspec.Meta(description='Specific exergy, in J/kg unless a unit is given')] | None | UnsetType = UNSET, e_CH: Annotated[float, msgspec.Meta(description='Specific exergy, in J/kg unless a unit is given')] | None | UnsetType = UNSET, mass_composition: dict[str, Annotated[float, msgspec.Meta(description='Mass or molar fraction'), Limit(gt=None, ge=0, le=1)]] | UnsetType = UNSET, molar_composition: dict[str, Annotated[float, msgspec.Meta(description='Mass or molar fraction'), Limit(gt=None, ge=0, le=1)]] | UnsetType = UNSET, x: float | None | UnsetType = UNSET, v: float | None | UnsetType = UNSET, VM: float | None | UnsetType = UNSET, *, source_component: str | None, target_component: str | None, source_connector: Annotated[int, msgspec.Meta(ge=0, description='0-based port index on the component')] | None = None, target_connector: Annotated[int, msgspec.Meta(ge=0, description='0-based port index on the component')] | None = None, source_component_type: int | str | None | UnsetType = UNSET)[source]¶
Bases:
_ConnectionBaseA stream of matter.
- class exerpy.schema.OtherConnection(*, source_component: str | None, target_component: str | None, source_connector: Annotated[int, msgspec.Meta(ge=0, description='0-based port index on the component')] | None = None, target_connector: Annotated[int, msgspec.Meta(ge=0, description='0-based port index on the component')] | None = None, source_component_type: int | str | None | UnsetType = UNSET)[source]¶
Bases:
_ConnectionBaseA logical connection (e.g. EBSILON control lines), carried but not analysed.
- class exerpy.schema.PowerConnection(energy_flow: Annotated[float, msgspec.Meta(description='Power, in W unless a unit is given')], *, source_component: str | None, target_component: str | None, source_connector: Annotated[int, msgspec.Meta(ge=0, description='0-based port index on the component')] | None = None, target_connector: Annotated[int, msgspec.Meta(ge=0, description='0-based port index on the component')] | None = None, source_component_type: int | str | None | UnsetType = UNSET)[source]¶
Bases:
_ConnectionBaseMechanical or electrical power; its exergy equals
energy_flow.
- class exerpy.schema.Settings(*, split_physical_exergy: bool | None = None, chemExLib: Literal['Ahrendts'] | None = None)[source]¶
Bases:
StructAnalysis options. Arguments to
from_jsontake precedence over these.
- exerpy.schema.check(data: bytes | str | dict, *, Tamb: float | None = None, pamb: float | None = None, chemExLib: str | None = None, split_physical_exergy: bool | None = None) tuple[ExerpyInput | None, list[Issue]][source]¶
Check the structure and then the values without raising, see
validate().Returns the model (
Noneif invalid) and all issues.
- exerpy.schema.check_structure(data: bytes | str | dict, *, Tamb: float | None = None, pamb: float | None = None, chemExLib: str | None = None, split_physical_exergy: bool | None = None) tuple[ExerpyInput | None, list[Issue]][source]¶
Check the structure of the input without raising, see
validate_structure().Returns the model (
Noneif invalid) and all issues.
- exerpy.schema.check_values(data: bytes | str | dict, *, Tamb: float | None = None, pamb: float | None = None) tuple[ExerpyInput | None, list[Issue]][source]¶
Check the values of the input without raising, see
validate_values().Returns the model (
Noneif invalid) and all issues.
- exerpy.schema.input_struct(component_type: str) type[Input][source]¶
The
Inputstruct of a component type, as found in the component registry.Deprecated types resolve to the type they are read as; an unknown type, or a registered class that declares no
Input, gets the baseComponent.Input.
- exerpy.schema.json_schema() dict[source]¶
JSON Schema (draft 2020-12) of the input, for editors and other tools.
componentslists each component type registered when this is called, with the fields of itsInputstruct.
- exerpy.schema.validate(data: bytes | str | dict, *, Tamb: float | None = None, pamb: float | None = None, chemExLib: str | None = None, split_physical_exergy: bool | None = None, log_warnings: bool = True) ExerpyInput[source]¶
Validate an ExerPy input document and return it as typed structs.
Runs
validate_structure()and, if the structure is valid,validate_values().- Parameters:
data (bytes, str or dict) – The JSON document, or the dictionary decoded from it (as the parsers build).
Tamb, pamb, chemExLib, split_physical_exergy (optional) – The overrides that will be passed to the analysis; they take precedence over the JSON, as in
exerpy.ExergyAnalysis.from_json().log_warnings (bool) – Log warnings through the ExerPy logger.
- Returns:
ExerpyInput – The validated document. Unknown keys are not part of it; the analysis keeps working on the original dictionary.
- Raises:
InputValidationError – A subclass of
ValueError.issueslists every finding, warnings included.
- exerpy.schema.validate_structure(data: bytes | str | dict, *, Tamb: float | None = None, pamb: float | None = None, chemExLib: str | None = None, split_physical_exergy: bool | None = None, log_warnings: bool = True) ExerpyInput[source]¶
Validate the structure of an ExerPy input document, as it is written.
Checks the required keys, the types, the
kindof each connection, the component types and names, the ports, the values the settings need, and the units. The values themselves are checked byvalidate_values(). Parameters, return value and errors are those ofvalidate().
- exerpy.schema.validate_values(data: bytes | str | dict, *, Tamb: float | None = None, pamb: float | None = None, log_warnings: bool = True) ExerpyInput[source]¶
Validate that each value of an ExerPy input document lies in its reasonable range.
The ranges are the
Limitof the types and hold in SI units, e.g. positive temperatures and pressures or mass fractions between 0 and 1. Mass fractions that do not add up to one give a warning. Parameters, return value and errors are those ofvalidate(); the document has to have a valid structure.