thermostat/src/config.rs

99 lines
3.0 KiB
Rust
Raw Normal View History

2020-09-24 07:18:33 +08:00
use crate::{
2020-09-26 07:40:01 +08:00
ad7172::PostFilter,
channels::Channels,
command_parser::{CenterPoint, Polarity},
2024-10-14 11:52:15 +08:00
pid, steinhart_hart,
};
use num_traits::Zero;
use serde::{Deserialize, Serialize};
use uom::si::f64::{ElectricCurrent, ElectricPotential};
2020-09-24 07:18:33 +08:00
2020-09-25 03:35:15 +08:00
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
2020-09-24 07:18:33 +08:00
pub struct ChannelConfig {
center: CenterPoint,
pid: pid::Parameters,
pid_target: f32,
pid_engaged: bool,
2024-05-17 15:25:13 +08:00
i_set: ElectricCurrent,
polarity: Polarity,
sh: steinhart_hart::Parameters,
2020-09-25 03:10:27 +08:00
pwm: PwmLimits,
2020-09-26 07:40:01 +08:00
/// uses variant `PostFilter::Invalid` instead of `None` to save space
adc_postfilter: PostFilter,
2020-09-24 07:18:33 +08:00
}
impl ChannelConfig {
2020-09-25 03:10:27 +08:00
pub fn new(channels: &mut Channels, channel: usize) -> Self {
let pwm = PwmLimits::new(channels, channel);
2020-09-26 07:40:01 +08:00
2024-10-14 11:52:15 +08:00
let adc_postfilter = channels
.adc
.get_postfilter(channel as u8)
2020-09-26 07:40:01 +08:00
.unwrap()
.unwrap_or(PostFilter::Invalid);
2020-09-25 03:10:27 +08:00
let state = channels.channel_state(channel);
2024-10-14 11:52:15 +08:00
let i_set = if state.pid_engaged {
ElectricCurrent::zero()
} else {
state.i_set
2024-05-17 15:25:13 +08:00
};
2020-09-24 07:18:33 +08:00
ChannelConfig {
center: state.center.clone(),
pid: state.pid.parameters.clone(),
pid_target: state.pid.target as f32,
pid_engaged: state.pid_engaged,
i_set,
polarity: state.polarity.clone(),
sh: state.sh.clone(),
2020-09-25 03:10:27 +08:00
pwm,
2020-09-26 07:40:01 +08:00
adc_postfilter,
2020-09-24 07:18:33 +08:00
}
}
2020-09-25 05:04:29 +08:00
pub fn apply(&self, channels: &mut Channels, channel: usize) {
let state = channels.channel_state(channel);
state.center = self.center.clone();
state.pid.parameters = self.pid.clone();
state.pid.target = self.pid_target.into();
state.pid_engaged = self.pid_engaged;
state.sh = self.sh.clone();
2020-09-26 07:40:01 +08:00
2020-09-25 05:04:29 +08:00
self.pwm.apply(channels, channel);
2020-09-26 07:40:01 +08:00
let adc_postfilter = match self.adc_postfilter {
PostFilter::Invalid => None,
adc_postfilter => Some(adc_postfilter),
};
let _ = channels.adc.set_postfilter(channel as u8, adc_postfilter);
2024-05-17 15:25:13 +08:00
let _ = channels.set_i(channel, self.i_set);
channels.set_polarity(channel, self.polarity.clone());
2020-09-25 05:04:29 +08:00
}
2020-09-24 07:18:33 +08:00
}
2020-09-25 02:59:04 +08:00
2020-09-25 03:35:15 +08:00
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct PwmLimits {
pub max_v: ElectricPotential,
pub max_i_pos: ElectricCurrent,
pub max_i_neg: ElectricCurrent,
2020-09-25 03:10:27 +08:00
}
impl PwmLimits {
pub fn new(channels: &mut Channels, channel: usize) -> Self {
let max_v = channels.get_max_v(channel);
let max_i_pos = channels.get_max_i_pos(channel);
let max_i_neg = channels.get_max_i_neg(channel);
2020-09-25 03:10:27 +08:00
PwmLimits {
max_v,
max_i_pos,
max_i_neg,
2020-09-25 03:10:27 +08:00
}
}
2020-09-25 05:04:29 +08:00
pub fn apply(&self, channels: &mut Channels, channel: usize) {
channels.set_max_v(channel, self.max_v);
channels.set_max_i_pos(channel, self.max_i_pos);
channels.set_max_i_neg(channel, self.max_i_neg);
2020-09-25 03:35:15 +08:00
}
2020-09-25 02:59:04 +08:00
}