Support fan PWM settings #73

Merged
sb10q merged 16 commits from esavkin/thermostat:69-fan_pwm into master 2023-03-22 17:15:49 +08:00
2 changed files with 104 additions and 53 deletions
Showing only changes of commit 33070abd81 - Show all commits

View File

@ -342,26 +342,29 @@ impl Handler {
Ok(Handler::Reset) Ok(Handler::Reset)
} }
fn fan(socket: &mut TcpSocket, fan_pwm: Option<u32>, fan_ctrl: &mut FanCtrl) -> Result<Handler, Error> { fn fan(socket: &mut TcpSocket, fan_pwm: u32, fan_ctrl: &mut FanCtrl) -> Result<Handler, Error> {
match fan_pwm { fan_ctrl.set_auto_mode(false);
Some(val) => { fan_ctrl.set_pwm(fan_pwm);
fan_ctrl.set_auto_mode(val == 0); send_line(socket, b"{}");
Outdated
Review

This behavior is inconsistent with the pwm command, the latter uses pwm i_set <current> / pwm pid, not pwm i_set 0 to enable PID.

This behavior is inconsistent with the ``pwm`` command, the latter uses ``pwm i_set <current> / pwm pid``, not ``pwm i_set 0`` to enable PID.
fan_ctrl.set_pwm(val); Ok(Handler::Handled)
}, }
None => {
match fan_ctrl.summary() { fn show_fan(socket: &mut TcpSocket, fan_ctrl: &mut FanCtrl) -> Result<Handler, Error> {
Ok(buf) => { match fan_ctrl.summary() {
send_line(socket, &buf); Ok(buf) => {
return Ok(Handler::Handled); send_line(socket, &buf);
Outdated
Review

Why does this get printed on !is_default_auto()? Looks like function naming or layout could still use some work....

Why does this get printed on ``!is_default_auto()``? Looks like function naming or layout could still use some work....
} Ok(Handler::Handled)
Err(e) => {
error!("unable to serialize fan summary: {:?}", e);
let _ = writeln!(socket, "{{\"error\":\"{:?}\"}}", e);
return Err(Error::ReportError);
}
};
} }
}; Err(e) => {
error!("unable to serialize fan summary: {:?}", e);
Outdated
Review

at your own risk

at your own risk
let _ = writeln!(socket, "{{\"error\":\"{:?}\"}}", e);
Err(Error::ReportError)
}
}
}
fn fan_auto(socket: &mut TcpSocket, fan_ctrl: &mut FanCtrl) -> Result<Handler, Error> {
fan_ctrl.set_auto_mode(true);
send_line(socket, b"{}"); send_line(socket, b"{}");
Ok(Handler::Handled) Ok(Handler::Handled)
Outdated
Review

Remove space before ( (also in the other functions)

Remove space before ( (also in the other functions)
} }
@ -401,9 +404,11 @@ impl Handler {
Command::Ipv4(config) => Handler::set_ipv4(socket, store, config), Command::Ipv4(config) => Handler::set_ipv4(socket, store, config),
Command::Reset => Handler::reset(&mut fan_ctrl.channels), Command::Reset => Handler::reset(&mut fan_ctrl.channels),
Command::Dfu => Handler::dfu(&mut fan_ctrl.channels), Command::Dfu => Handler::dfu(&mut fan_ctrl.channels),
Command::Fan {fan_pwm} => Handler::fan(socket, fan_pwm, fan_ctrl), Command::FanSet {fan_pwm} => Handler::fan(socket, fan_pwm, fan_ctrl),
Command::ShowFan => Handler::show_fan(socket, fan_ctrl),
Command::FanAuto => Handler::fan_auto(socket, fan_ctrl),
Command::FanCurve { k_a, k_b, k_c } => Handler::fan_curve(socket, fan_ctrl, k_a, k_b, k_c), Command::FanCurve { k_a, k_b, k_c } => Handler::fan_curve(socket, fan_ctrl, k_a, k_b, k_c),
Command::FanDefaults => Handler::fan_defaults(socket, fan_ctrl), Command::FanCurveDefaults => Handler::fan_defaults(socket, fan_ctrl),
} }
} }
} }

View File

@ -179,15 +179,17 @@ pub enum Command {
rate: Option<f32>, rate: Option<f32>,
}, },
Dfu, Dfu,
Fan { FanSet {
fan_pwm: Option<u32> fan_pwm: u32
}, },
FanAuto,
ShowFan,
FanCurve { FanCurve {
k_a: f64, k_a: f64,
k_b: f64, k_b: f64,
k_c: f64, k_c: f64,
}, },
FanDefaults, FanCurveDefaults,
} }
fn end(input: &[u8]) -> IResult<&[u8], ()> { fn end(input: &[u8]) -> IResult<&[u8], ()> {
@ -532,45 +534,56 @@ fn ipv4(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
fn fan(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> { fn fan(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
let (input, _) = tag("fan")(input)?; let (input, _) = tag("fan")(input)?;
let (input, fan_pwm) = alt(( alt((
|input| { |input| {
let (input, _) = whitespace(input)?; let (input, _) = whitespace(input)?;
let (input, value) = unsigned(input)?;
let (input, _) = end(input)?;
Ok((input, Some(value.unwrap_or(0))))
},
value(None, end)
))(input)?;
let result = Ok(Command::Fan { fan_pwm }); let (input, result) = alt((
Ok((input, result)) |input| {
let (input, _) = tag("auto")(input)?;
Ok((input, Ok(Command::FanAuto)))
},
|input| {
let (input, value) = unsigned(input)?;
Ok((input, Ok(Command::FanSet { fan_pwm: value.unwrap_or(0)})))
},
))(input)?;
let (input, _) = end(input)?;
Ok((input, result))
},
value(Ok(Command::ShowFan), end)
))(input)
} }
fn fan_curve(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> { fn fan_curve(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
let (input, _) = tag("fcurve")(input)?; let (input, _) = tag("fcurve")(input)?;
let (input, curve) = alt(( alt((
|input| { |input| {
let (input, _) = whitespace(input)?; let (input, _) = whitespace(input)?;
let (input, k_a) = float(input)?; let (input, result) = alt((
let (input, _) = whitespace(input)?; |input| {
let (input, k_b) = float(input)?; let (input, _) = tag("default")(input)?;
let (input, _) = whitespace(input)?; Ok((input, Ok(Command::FanCurveDefaults)))
let (input, k_c) = float(input)?; },
|input| {
let (input, k_a) = float(input)?;
let (input, _) = whitespace(input)?;
Outdated
Review

Call it "curve" or "coeff" but not both.

Call it "curve" or "coeff" but not both.
let (input, k_b) = float(input)?;
let (input, _) = whitespace(input)?;
let (input, k_c) = float(input)?;
let (input, _) = end(input)?;
if k_a.is_ok() && k_b.is_ok() && k_c.is_ok() {
Ok((input, Ok(Command::FanCurve { k_a: k_a.unwrap(), k_b: k_b.unwrap(), k_c: k_c.unwrap() })))
} else {
Err(nom::Err::Incomplete(Needed::Size(3)))
}
},
))(input)?;
let (input, _) = end(input)?; let (input, _) = end(input)?;
if k_a.is_ok() && k_b.is_ok() && k_c.is_ok() { Ok((input, result))
Ok((input, Some((k_a.unwrap(), k_b.unwrap(), k_c.unwrap()))))
} else {
Err(nom::Err::Incomplete(Needed::Size(3)))
}
}, },
value(None, end) value(Err(Error::Incomplete), end)
))(input)?; ))(input)
let result = match curve {
Some(curve) => Ok(Command::FanCurve { k_a: curve.0, k_b: curve.1, k_c: curve.2 }),
None => Err(Error::ParseFloat)
};
Ok((input, result))
} }
fn command(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> { fn command(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
@ -586,7 +599,6 @@ fn command(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
steinhart_hart, steinhart_hart,
postfilter, postfilter,
value(Ok(Command::Dfu), tag("dfu")), value(Ok(Command::Dfu), tag("dfu")),
value(Ok(Command::FanDefaults), tag("fcurve-restore")),
fan, fan,
fan_curve, fan_curve,
))(input) ))(input)
@ -810,4 +822,38 @@ mod test {
center: CenterPoint::Vref, center: CenterPoint::Vref,
})); }));
} }
#[test]
fn parse_fan_show() {
let command = Command::parse(b"fan");
assert_eq!(command, Ok(Command::ShowFan));
}
#[test]
fn parse_fan_set() {
let command = Command::parse(b"fan 42");
assert_eq!(command, Ok(Command::FanSet {fan_pwm: 42}));
}
#[test]
fn parse_fan_auto() {
let command = Command::parse(b"fan auto");
assert_eq!(command, Ok(Command::FanAuto));
}
#[test]
fn parse_fcurve_set() {
let command = Command::parse(b"fcurve 1.2 3.4 5.6");
assert_eq!(command, Ok(Command::FanCurve {
k_a: 1.2,
k_b: 3.4,
k_c: 5.6
}));
}
#[test]
fn parse_fcurve_default() {
let command = Command::parse(b"fcurve default");
assert_eq!(command, Ok(Command::FanCurveDefaults));
}
} }