Skip to content

Commit

Permalink
add restriction to input that only storage tanks are valid for pre-he…
Browse files Browse the repository at this point in the history
…ated water sources, update input json schema
  • Loading branch information
shieldo committed Feb 14, 2025
1 parent 118d328 commit d6f47ac
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 84 deletions.
169 changes: 86 additions & 83 deletions schemas/input.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@
{
"type": "object",
"additionalProperties": {
"$ref": "#/$defs/HotWaterSourceDetails"
"$ref": "#/$defs/StorageTank"
}
},
{
Expand Down Expand Up @@ -3355,88 +3355,7 @@
"HotWaterSourceDetails": {
"oneOf": [
{
"type": "object",
"title": "StorageTank",
"required": [
"ColdWaterSource",
"HeatSource",
"daily_losses",
"type",
"volume"
],
"properties": {
"ColdWaterSource": {
"type": "string"
},
"Control_hold_at_setpnt": {
"type": [
"string",
"null"
]
},
"HeatSource": {
"type": "object",
"additionalProperties": {
"$ref": "#/$defs/HeatSource"
}
},
"daily_losses": {
"type": "number",
"format": "double",
"description": "Measured standby losses due to cylinder insulation at standardised conditions (unit: kWh/24h)"
},
"heat_exchanger_surface_area": {
"type": [
"number",
"null"
],
"format": "double"
},
"init_temp": {
"type": [
"number",
"null"
],
"format": "double"
},
"min_temp": {
"type": [
"number",
"null"
],
"format": "double",
"description": "Minimum temperature required for domestic hot water (unit: ˚C)"
},
"primary_pipework": {
"type": [
"array",
"null"
],
"items": {
"$ref": "#/$defs/WaterPipework"
}
},
"setpoint_temp": {
"type": [
"number",
"null"
],
"format": "double",
"description": "Setpoint temperature (unit: ˚C)"
},
"type": {
"type": "string",
"enum": [
"StorageTank"
]
},
"volume": {
"type": "number",
"format": "double",
"description": "Total volume of tank (unit: litre)"
}
},
"additionalProperties": false
"$ref": "#/$defs/StorageTank"
},
{
"type": "object",
Expand Down Expand Up @@ -4981,6 +4900,90 @@
},
"additionalProperties": false
},
"StorageTank": {
"type": "object",
"title": "StorageTank",
"required": [
"ColdWaterSource",
"HeatSource",
"daily_losses",
"type",
"volume"
],
"properties": {
"ColdWaterSource": {
"type": "string"
},
"Control_hold_at_setpnt": {
"type": [
"string",
"null"
]
},
"HeatSource": {
"type": "object",
"additionalProperties": {
"$ref": "#/$defs/HeatSource"
}
},
"daily_losses": {
"type": "number",
"format": "double",
"description": "Measured standby losses due to cylinder insulation at standardised conditions (unit: kWh/24h)"
},
"heat_exchanger_surface_area": {
"type": [
"number",
"null"
],
"format": "double"
},
"init_temp": {
"type": [
"number",
"null"
],
"format": "double"
},
"min_temp": {
"type": [
"number",
"null"
],
"format": "double",
"description": "Minimum temperature required for domestic hot water (unit: ˚C)"
},
"primary_pipework": {
"type": [
"array",
"null"
],
"items": {
"$ref": "#/$defs/WaterPipework"
}
},
"setpoint_temp": {
"type": [
"number",
"null"
],
"format": "double",
"description": "Setpoint temperature (unit: ˚C)"
},
"type": {
"type": "string",
"enum": [
"StorageTank"
]
},
"volume": {
"type": "number",
"format": "double",
"description": "Total volume of tank (unit: litre)"
}
},
"additionalProperties": false
},
"StorageTankType": {
"type": "string",
"enum": [
Expand Down
12 changes: 11 additions & 1 deletion src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub fn ingest_for_processing(json: impl Read) -> Result<InputForProcessing, anyh
InputForProcessing::init_with_json(json)
}

#[derive(Clone, Debug, Deserialize, Serialize)]
#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[cfg_attr(test, derive(PartialEq))]
Expand All @@ -40,6 +40,7 @@ pub struct Input {
pub appliance_gains: ApplianceGains,
pub cold_water_source: ColdWaterSourceInput,
#[serde(default)]
#[validate(custom = validate_only_storage_tanks)]
pub(crate) pre_heated_water_source: IndexMap<String, HotWaterSourceDetails>,
pub(crate) energy_supply: EnergySupplyInput,
pub control: Control,
Expand Down Expand Up @@ -96,6 +97,15 @@ pub struct Input {
pub tariff: Option<Tariff>,
}

fn validate_only_storage_tanks(
sources: &IndexMap<String, HotWaterSourceDetails>,
) -> Result<(), serde_valid::validation::Error> {
sources.values()
.all(|details| matches!(details, HotWaterSourceDetails::StorageTank { .. }))
.then(|| ())
.ok_or_else(|| serde_valid::validation::Error::Custom("PreHeatedWaterSource input can only contain HotWaterSource data of the type StorageTank".to_owned()))
}

#[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
Expand Down

0 comments on commit d6f47ac

Please sign in to comment.