Legg til barnehage, kontor-, skole-, idretts- og kulturbygg

Driftstidene har nå dager per uke og uker per år, og lastene gjelder bare på driftsdager.
Normerte verdier for de nye kategoriene er hentet fra publiserte Simien-utskrifter og
DiBK-utredninger og kontrollert mot energibudsjettene i de samme kildene. Boligblokk har
fått egne verdier i stedet for en kopi av småhus.

Balanserte anlegg kan ha kjølebatteri, og varmegjenvinneren reguleres ned når den ellers
ville varmet tilluften over settpunktet.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015GeH3y8fwTaTudaD88P57o
This commit is contained in:
bl
2026-09-15 20:05:20 +02:00
co-authored by Claude Opus 5
parent cb64c91b19
commit d02a3d9666
16 changed files with 601 additions and 39 deletions
+45 -2
View File
@@ -14,6 +14,11 @@ const MATERIALER: &str = include_str!("../data/materialer.toml");
const KLIMAKORREKSJON: &str = include_str!("../data/klimakorreksjon.csv");
const NORMERTE_SMAAHUS: &str = include_str!("../data/normerte/smaahus.toml");
const NORMERTE_BOLIGBLOKK: &str = include_str!("../data/normerte/boligblokk.toml");
const NORMERTE_BARNEHAGE: &str = include_str!("../data/normerte/barnehage.toml");
const NORMERTE_KONTORBYGG: &str = include_str!("../data/normerte/kontorbygg.toml");
const NORMERTE_SKOLEBYGG: &str = include_str!("../data/normerte/skolebygg.toml");
const NORMERTE_IDRETTSBYGG: &str = include_str!("../data/normerte/idrettsbygg.toml");
const NORMERTE_KULTURBYGG: &str = include_str!("../data/normerte/kulturbygg.toml");
/// Katalog som kan overstyre de innebygde datafilene.
#[derive(Clone, Debug, Default)]
@@ -63,8 +68,13 @@ impl Datakilde {
let (fil, innebygd) = match kategori {
Kategori::Smaahus => ("normerte/smaahus.toml", NORMERTE_SMAAHUS),
Kategori::Boligblokk => ("normerte/boligblokk.toml", NORMERTE_BOLIGBLOKK),
Kategori::Barnehage => ("normerte/barnehage.toml", NORMERTE_BARNEHAGE),
Kategori::Kontorbygg => ("normerte/kontorbygg.toml", NORMERTE_KONTORBYGG),
Kategori::Skolebygg => ("normerte/skolebygg.toml", NORMERTE_SKOLEBYGG),
Kategori::Idrettsbygg => ("normerte/idrettsbygg.toml", NORMERTE_IDRETTSBYGG),
Kategori::Kulturbygg => ("normerte/kulturbygg.toml", NORMERTE_KULTURBYGG),
annen => {
// Andre kategorier krever egen datafil i data-katalogen.
// Kategorier uten offentlig tilgjengelige normerte verdier krever egen datafil.
let fil = format!("normerte/{}.toml", annen.nokkel());
let p = self
.katalog
@@ -257,9 +267,12 @@ pub struct Settpunkt {
pub oppvarming_natt: f64,
pub kjoling: f64,
pub ventilasjon_tilluft: f64,
/// Tilluftstemperatur når anlegget har kjølebatteri. Utelatt: lik `ventilasjon_tilluft`.
#[serde(default)]
pub ventilasjon_tilluft_kjoling: Option<f64>,
}
#[derive(Deserialize, Clone, Debug)]
#[derive(Deserialize, serde::Serialize, Clone, Debug)]
pub struct Driftstider {
pub oppvarming: Tidsrom,
pub belysning: Tidsrom,
@@ -267,13 +280,43 @@ pub struct Driftstider {
pub varmtvann: Tidsrom,
pub personer: Tidsrom,
pub ventilasjon: Tidsrom,
/// Driftsdager per uke, regnet fra mandag (NS 3031 Tabell A.3).
#[serde(default = "sju")]
pub dager_per_uke: u8,
/// Driftsuker per år (NS 3031 Tabell A.3). Ukene uten drift legges i ferier, se [`FERIEUKER`].
#[serde(default = "femtito")]
pub uker_per_aar: u8,
}
fn sju() -> u8 {
7
}
fn femtito() -> u8 {
52
}
/// Uker uten drift, i den rekkefølgen de tas ut når en kategori har færre enn 52 driftsuker:
/// fellesferien først, deretter jul, vinterferie, påske og høstferie, og så uke for uke
/// utover sommeren og nyttår.
pub const FERIEUKER: [u8; 16] = [28, 29, 30, 31, 27, 32, 52, 8, 14, 40, 26, 33, 1, 25, 34, 9];
impl Driftstider {
/// Om døgn nummer `dag` (0 = 1. januar) er en driftsdag.
///
/// Året regnes å begynne på en mandag. Døgn 364 hører til uke 52.
pub fn driftsdag(&self, dag: usize) -> bool {
if dag % 7 >= self.dager_per_uke.min(7) as usize {
return false;
}
let uke = (dag / 7 + 1).min(52) as u8;
let fri = (52u8.saturating_sub(self.uker_per_aar) as usize).min(FERIEUKER.len());
!FERIEUKER[..fri].contains(&uke)
}
pub fn driftsdager_per_aar(&self) -> usize {
(0..365).filter(|&d| self.driftsdag(d)).count()
}
}
#[derive(Deserialize, serde::Serialize, Clone, Copy, Debug)]
pub struct Tidsrom {