1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
use serde::Deserialize;
use serde_with::serde_as;
use serde_with::DurationSeconds;
use std::time::Duration;
#[serde_as]
#[derive(Clone, Deserialize, Debug, PartialEq)]
#[serde(default, deny_unknown_fields)]
pub struct HeatPumpCirculationConfig {
/// How long (in seconds) the heat pump should stay on for before turning off
/// (Should be less than the time it takes for it to turn on)
/// TODO: Unused?
#[serde_as(as = "DurationSeconds")]
pub hp_pump_on_time: Duration,
/// How long (in seconds) the heat pump should stay off before turning back on.
/// TODO: Unused?
#[serde_as(as = "DurationSeconds")]
pub hp_pump_off_time: Duration,
/// How long (in seconds) to sleep after going from On -> Circulation mode, and
/// also, how long to stay in Equalise mode before giving up.
#[serde_as(as = "DurationSeconds")]
pub initial_hp_sleep: Duration,
/// The temperature required on HXOR to go into pre circulate rather than directly to
/// circulate.
pub pre_circulate_temp_required: f32,
/// The amount to subtract from the difference of TKBT and HXOR as the first step.
pub forecast_diff_offset: f32,
/// The proportion of the difference between TKBT and HXOR subtract from TKBT to make the
/// forecasted temperature.
pub forecast_diff_proportion: f32,
/// The percentage i.e 0.33 that it needs to be above the bottom when first starting.
pub forecast_start_above_percent: f32,
/// The steady-state drop between TKBT (Tank Bottom) and HXIA (Heat Exchanger Input Average)
pub forecast_tkbt_hxia_drop: f32,
/// The threshold of the forecast heat exchanger temperature needs to be in the working
/// range in order to go into a mixed heating mode (if there is demand for hot water)
pub mixed_mode: MixedModeConfig,
/// When to enter boost mode whereby the heat pump is on and the heating is boosted
/// by taking heat from the hot water tank
pub boost_mode: BoostModeConfig,
/// How long to sample draining the tank to see whether it is effective.
#[serde_as(as = "DurationSeconds")]
pub sample_tank_time: Duration,
}
#[serde_as]
#[derive(Clone, Deserialize, Debug, PartialEq)]
pub struct MixedModeConfig {
pub start_heat_pct: f32,
pub stop_heat_pct: f32,
}
#[serde_as]
#[derive(Clone, Deserialize, Debug, PartialEq)]
pub struct BoostModeConfig {
/// The maximum percentage within the heating range to start boosting
/// Lower than this the rooms will heat up sufficiently quickly without boosting
pub start_heat_pct: f32,
/// The maximum percentage within the heating range to continue boosting once started
/// If too close to start_heat_pct then this will result in excessive valve movement
/// to little effect.
pub stop_heat_pct: f32,
/// The minimum difference between the TKFL and HPFL to start boosting
/// Lower than this would achieve very little.
pub start_tkfl_hpfl_diff: f32,
/// The minimum difference between the TKFL and HPFL to continue boosting once started
/// If too close to start_tkfl_hpfl_diff then this will result in excessive valve movement
/// to little effect.
pub stop_tkfl_hpfl_diff: f32,
/// The minimum difference between the configured minimum tank temperature for the current
/// slot to start boosting
pub start_slot_min_diff: f32,
/// The minimum difference between the configured minimum tank temperature for the current
/// slot to continue boosting once started
/// If too close to start_slot_min_diff then this will result in excessive valve movement
/// to little effect.
pub stop_slot_min_diff: f32,
}
impl Default for HeatPumpCirculationConfig {
fn default() -> Self {
Self {
hp_pump_on_time: Duration::from_secs(70),
hp_pump_off_time: Duration::from_secs(30),
initial_hp_sleep: Duration::from_secs(5 * 60),
forecast_diff_offset: 5.0,
forecast_diff_proportion: 0.33,
forecast_start_above_percent: 0.10,
forecast_tkbt_hxia_drop: 3.0,
pre_circulate_temp_required: 35.0,
mixed_mode: MixedModeConfig {
start_heat_pct: 0.70,
stop_heat_pct: 0.30,
},
boost_mode: BoostModeConfig {
start_heat_pct: 0.00,
stop_heat_pct: 0.10,
start_tkfl_hpfl_diff: 2.0,
stop_tkfl_hpfl_diff: 1.0,
start_slot_min_diff: 3.5,
stop_slot_min_diff: 1.5,
},
sample_tank_time: Duration::from_secs(30),
}
}
}