From d7496e3362d860f9a3917f58852c78818e18e0b3 Mon Sep 17 00:00:00 2001 From: atse Date: Thu, 15 Aug 2024 17:38:03 +0800 Subject: [PATCH] TCP command: Rename `pwm` to `output` Current limit pins are driven by PWM inputs to the MAX1968 driver, but this is an implementation detail, and should not be exposed in the form of the command interface. Rename "pwm" to "output" in all instances. See https://git.m-labs.hk/M-Labs/thermostat/issues/62#issue-725. --- README.md | 86 +++++++++++++++++++++--------------------- pytec/autotune.py | 4 +- pytec/example.py | 4 +- pytec/pytec/client.py | 18 ++++----- src/channels.rs | 10 ++--- src/command_handler.rs | 10 ++--- src/command_parser.rs | 66 ++++++++++++++++---------------- 7 files changed, 99 insertions(+), 99 deletions(-) diff --git a/README.md b/README.md index 93e8dc3..dc245bf 100644 --- a/README.md +++ b/README.md @@ -92,41 +92,41 @@ ADC input data is provided in reports. Query for the latest report with the comm Send commands as simple text string terminated by `\n`. Responses are formatted as line-delimited JSON. -| Syntax | Function | -|------------------------------------------- |-------------------------------------------------------------------------------| -| `report` | Show current input | -| `pwm` | Show current PWM settings | -| `pwm <0/1> max_i_pos ` | Set maximum positive output current, clamped to [0, 2] | -| `pwm <0/1> max_i_neg ` | Set maximum negative output current, clamped to [0, 2] | -| `pwm <0/1> max_v ` | Set maximum output voltage, clamped to [0, 4] | -| `pwm <0/1> i_set ` | Disengage PID, set fixed output current, clamped to [-2, 2] | -| `pwm <0/1> polarity ` | Set output current polarity, with 'normal' being the front panel polarity | -| `pwm <0/1> pid` | Let output current to be controlled by the PID | -| `center <0/1> ` | Set the MAX1968 0A-centerpoint to the specified fixed voltage | -| `center <0/1> vref` | Set the MAX1968 0A-centerpoint to measure from VREF | -| `pid` | Show PID configuration | -| `pid <0/1> target ` | Set the PID controller target temperature | -| `pid <0/1> kp ` | Set proportional gain | -| `pid <0/1> ki ` | Set integral gain | -| `pid <0/1> kd ` | Set differential gain | -| `pid <0/1> output_min ` | Set mininum output | -| `pid <0/1> output_max ` | Set maximum output | -| `s-h` | Show Steinhart-Hart equation parameters | -| `s-h <0/1> ` | Set Steinhart-Hart parameter for a channel | -| `postfilter` | Show postfilter settings | -| `postfilter <0/1> off` | Disable postfilter | -| `postfilter <0/1> rate ` | Set postfilter output data rate | -| `load [0/1]` | Restore configuration for channel all/0/1 from flash | -| `save [0/1]` | Save configuration for channel all/0/1 to flash | -| `reset` | Reset the device | -| `dfu` | Reset device and enters USB device firmware update (DFU) mode | -| `ipv4 [Y.Y.Y.Y]` | Configure IPv4 address, netmask length, and optional default gateway | -| `fan` | Show current fan settings and sensors' measurements | -| `fan ` | Set fan power with values from 1 to 100 | -| `fan auto` | Enable automatic fan speed control | -| `fcurve ` | Set fan controller curve coefficients (see *Fan control* section) | -| `fcurve default` | Set fan controller curve coefficients to defaults (see *Fan control* section) | -| `hwrev` | Show hardware revision, and settings related to it | +| Syntax | Function | +|-------------------------------------------|-------------------------------------------------------------------------------| +| `report` | Show current input | +| `output` | Show current output settings | +| `output <0/1> max_i_pos ` | Set maximum positive output current, clamped to [0, 2] | +| `output <0/1> max_i_neg ` | Set maximum negative output current, clamped to [0, 2] | +| `output <0/1> max_v ` | Set maximum output voltage, clamped to [0, 4] | +| `output <0/1> i_set ` | Disengage PID, set fixed output current, clamped to [-2, 2] | +| `output <0/1> polarity ` | Set output current polarity, with 'normal' being the front panel polarity | +| `output <0/1> pid` | Let output current to be controlled by the PID | +| `center <0/1> ` | Set the MAX1968 0A-centerpoint to the specified fixed voltage | +| `center <0/1> vref` | Set the MAX1968 0A-centerpoint to measure from VREF | +| `pid` | Show PID configuration | +| `pid <0/1> target ` | Set the PID controller target temperature | +| `pid <0/1> kp ` | Set proportional gain | +| `pid <0/1> ki ` | Set integral gain | +| `pid <0/1> kd ` | Set differential gain | +| `pid <0/1> output_min ` | Set mininum output | +| `pid <0/1> output_max ` | Set maximum output | +| `s-h` | Show Steinhart-Hart equation parameters | +| `s-h <0/1> ` | Set Steinhart-Hart parameter for a channel | +| `postfilter` | Show postfilter settings | +| `postfilter <0/1> off` | Disable postfilter | +| `postfilter <0/1> rate ` | Set postfilter output data rate | +| `load [0/1]` | Restore configuration for channel all/0/1 from flash | +| `save [0/1]` | Save configuration for channel all/0/1 to flash | +| `reset` | Reset the device | +| `dfu` | Reset device and enters USB device firmware update (DFU) mode | +| `ipv4 [Y.Y.Y.Y]` | Configure IPv4 address, netmask length, and optional default gateway | +| `fan` | Show current fan settings and sensors' measurements | +| `fan ` | Set fan power with values from 1 to 100 | +| `fan auto` | Enable automatic fan speed control | +| `fcurve ` | Set fan controller curve coefficients (see *Fan control* section) | +| `fcurve default` | Set fan controller curve coefficients to defaults (see *Fan control* section) | +| `hwrev` | Show hardware revision, and settings related to it | ## USB @@ -183,7 +183,7 @@ postfilter rate can be tuned with the `postfilter` command. When using a TEC module with the Thermostat, the Thermostat expects the thermal load (where the thermistor is located) to cool down with a positive software current set point, and heat up with a negative current set point. -If the Thermostat is used for temperature control with the Sinara 5432 DAC "Zotino", and is connected via an IDC cable, the TEC polarity may need to be reversed with the `pwm polarity reversed` TCP command. +If the Thermostat is used for temperature control with the Sinara 5432 DAC "Zotino", and is connected via an IDC cable, the TEC polarity may need to be reversed with the `output polarity reversed` TCP command. Testing heat flow direction with a low set current is recommended before installation of the TEC module. @@ -192,7 +192,7 @@ Testing heat flow direction with a low set current is recommended before install Each of the MAX1968 TEC driver has analog/PWM inputs for setting output limits. -Use the `pwm` command to see current settings and maximum values. +Use the `output` command to see current settings and maximum values. | Limit | Unit | Description | | --- | :---: | --- | @@ -203,28 +203,28 @@ Use the `pwm` command to see current settings and maximum values. Example: set the maximum voltage of channel 0 to 1.5 V. ``` -pwm 0 max_v 1.5 +output 0 max_v 1.5 ``` Example: set the maximum negative current of channel 0 to -3 A. ``` -pwm 0 max_i_neg 3 +output 0 max_i_neg 3 ``` Example: set the maximum positive current of channel 1 to 3 A. ``` -pwm 0 max_i_pos 3 +output 0 max_i_pos 3 ``` ### Open-loop mode To manually control TEC output current, omit the limit parameter of -the `pwm` command. Doing so will disengage the PID control for that +the `output` command. Doing so will disengage the PID control for that channel. Example: set output current of channel 0 to 0 A. ``` -pwm 0 i_set 0 +output 0 i_set 0 ``` ## PID-stabilized temperature control @@ -237,7 +237,7 @@ pid 0 target 20 Enter closed-loop mode by switching control of the TEC output current of channel 0 to the PID algorithm: ``` -pwm 0 pid +output 0 pid ``` ## LED indicators diff --git a/pytec/autotune.py b/pytec/autotune.py index c1f593e..360d06c 100644 --- a/pytec/autotune.py +++ b/pytec/autotune.py @@ -253,9 +253,9 @@ def main(): tuner_out = tuner.output() - tec.set_param("pwm", channel, "i_set", tuner_out) + tec.set_param("output", channel, "i_set", tuner_out) - tec.set_param("pwm", channel, "i_set", 0) + tec.set_param("output", channel, "i_set", 0) if __name__ == "__main__": diff --git a/pytec/example.py b/pytec/example.py index 001ea49..50dd6b1 100644 --- a/pytec/example.py +++ b/pytec/example.py @@ -2,9 +2,9 @@ from pytec.client import Client tec = Client() #(host="localhost", port=6667) tec.set_param("s-h", 1, "t0", 20) -print(tec.get_pwm()) +print(tec.get_output()) print(tec.get_pid()) -print(tec.get_pwm()) +print(tec.get_output()) print(tec.get_postfilter()) print(tec.get_steinhart_hart()) for data in tec.report_mode(): diff --git a/pytec/pytec/client.py b/pytec/pytec/client.py index 9862fe5..7781524 100644 --- a/pytec/pytec/client.py +++ b/pytec/pytec/client.py @@ -13,11 +13,11 @@ class Client: self._check_zero_limits() def _check_zero_limits(self): - pwm_report = self.get_pwm() - for pwm_channel in pwm_report: + output_report = self.get_output() + for output_channel in output_report: for limit in ["max_i_neg", "max_i_pos", "max_v"]: - if pwm_channel[limit] == 0.0: - logging.warning("`{}` limit is set to zero on channel {}".format(limit, pwm_channel["channel"])) + if output_channel[limit] == 0.0: + logging.warning("`{}` limit is set to zero on channel {}".format(limit, output_channel["channel"])) def _read_line(self): # read more lines @@ -47,8 +47,8 @@ class Client: result[int(item["channel"])] = item return result - def get_pwm(self): - """Retrieve PWM limits for the TEC + def get_output(self): + """Retrieve output limits for the TEC Example:: [{'channel': 0, @@ -67,7 +67,7 @@ class Client: 'polarity': 'normal', ] """ - return self._get_conf("pwm") + return self._get_conf("output") def get_pid(self): """Retrieve PID control state @@ -144,7 +144,7 @@ class Client: """Set configuration parameters Examples:: - tec.set_param("pwm", 0, "max_v", 2.0) + tec.set_param("output", 0, "max_v", 2.0) tec.set_param("pid", 1, "output_max", 2.5) tec.set_param("s-h", 0, "t0", 20.0) tec.set_param("center", 0, "vref") @@ -161,7 +161,7 @@ class Client: def power_up(self, channel, target): """Start closed-loop mode""" self.set_param("pid", channel, "target", value=target) - self.set_param("pwm", channel, "pid") + self.set_param("output", channel, "pid") def save_config(self): """Save current configuration to EEPROM""" diff --git a/src/channels.rs b/src/channels.rs index d8300c0..ce80c2c 100644 --- a/src/channels.rs +++ b/src/channels.rs @@ -507,8 +507,8 @@ impl Channels { false } - fn pwm_summary(&mut self, channel: usize) -> PwmSummary { - PwmSummary { + fn output_summary(&mut self, channel: usize) -> OutputSummary { + OutputSummary { channel, center: CenterPointJson(self.channel_state(channel).center.clone()), i_set: self.get_i(channel), @@ -519,10 +519,10 @@ impl Channels { } } - pub fn pwm_summaries_json(&mut self) -> Result { + pub fn output_summaries_json(&mut self) -> Result { let mut summaries = Vec::<_, U2>::new(); for channel in 0..CHANNELS { - let _ = summaries.push(self.pwm_summary(channel)); + let _ = summaries.push(self.output_summary(channel)); } serde_json_core::to_vec(&summaries) } @@ -613,7 +613,7 @@ impl Serialize for PolarityJson { } #[derive(Serialize)] -pub struct PwmSummary { +pub struct OutputSummary { channel: usize, center: CenterPointJson, i_set: ElectricCurrent, diff --git a/src/command_handler.rs b/src/command_handler.rs index 6fd1d1e..1bd542f 100644 --- a/src/command_handler.rs +++ b/src/command_handler.rs @@ -116,7 +116,7 @@ impl Handler { } fn show_pwm(socket: &mut TcpSocket, channels: &mut Channels) -> Result { - match channels.pwm_summaries_json() { + match channels.output_summaries_json() { Ok(buf) => { send_line(socket, &buf); } @@ -413,13 +413,13 @@ impl Handler { Command::Quit => Ok(Handler::CloseSocket), Command::Show(ShowCommand::Input) => Handler::show_report(socket, channels), Command::Show(ShowCommand::Pid) => Handler::show_pid(socket, channels), - Command::Show(ShowCommand::Pwm) => Handler::show_pwm(socket, channels), + Command::Show(ShowCommand::Output) => Handler::show_pwm(socket, channels), Command::Show(ShowCommand::SteinhartHart) => Handler::show_steinhart_hart(socket, channels), Command::Show(ShowCommand::PostFilter) => Handler::show_post_filter(socket, channels), Command::Show(ShowCommand::Ipv4) => Handler::show_ipv4(socket, ipv4_config), - Command::PwmPid { channel } => Handler::engage_pid(socket, channels, channel), - Command::PwmPolarity { channel, polarity } => Handler::set_polarity(socket, channels, channel, polarity), - Command::Pwm { channel, pin, value } => Handler::set_pwm(socket, channels, channel, pin, value), + Command::OutputPid { channel } => Handler::engage_pid(socket, channels, channel), + Command::OutputPolarity { channel, polarity } => Handler::set_polarity(socket, channels, channel, polarity), + Command::Output { channel, pin, value } => Handler::set_pwm(socket, channels, channel, pin, value), Command::CenterPoint { channel, center } => Handler::set_center_point(socket, channels, channel, center), Command::Pid { channel, parameter, value } => Handler::set_pid(socket, channels, channel, parameter, value), Command::SteinhartHart { channel, parameter, value } => Handler::set_steinhart_hart(socket, channels, channel, parameter, value), diff --git a/src/command_parser.rs b/src/command_parser.rs index 5eb3589..eebd3fe 100644 --- a/src/command_parser.rs +++ b/src/command_parser.rs @@ -96,7 +96,7 @@ pub struct Ipv4Config { #[derive(Debug, Clone, PartialEq)] pub enum ShowCommand { Input, - Pwm, + Output, Pid, SteinhartHart, PostFilter, @@ -154,16 +154,16 @@ pub enum Command { Ipv4(Ipv4Config), Show(ShowCommand), /// PWM parameter setting - Pwm { + Output { channel: usize, pin: PwmPin, value: f64, }, /// Enable PID control for `i_set` - PwmPid { + OutputPid { channel: usize, }, - PwmPolarity { + OutputPolarity { channel: usize, polarity: Polarity, }, @@ -302,12 +302,12 @@ fn pwm_setup(input: &[u8]) -> IResult<&[u8], Result<(PwmPin, f64), Error>> { )(input) } -/// `pwm <0-1> pid` - Set PWM to be controlled by PID -fn pwm_pid(input: &[u8]) -> IResult<&[u8], ()> { +/// `output <0-1> pid` - Set output to be controlled by PID +fn output_pid(input: &[u8]) -> IResult<&[u8], ()> { value((), tag("pid"))(input) } -fn pwm_polarity(input: &[u8]) -> IResult<&[u8], Polarity> { +fn output_polarity(input: &[u8]) -> IResult<&[u8], Polarity> { preceded( tag("polarity"), preceded( @@ -319,8 +319,8 @@ fn pwm_polarity(input: &[u8]) -> IResult<&[u8], Polarity> { )(input) } -fn pwm(input: &[u8]) -> IResult<&[u8], Result> { - let (input, _) = tag("pwm")(input)?; +fn output(input: &[u8]) -> IResult<&[u8], Result> { + let (input, _) = tag("output")(input)?; alt(( |input| { let (input, _) = whitespace(input)?; @@ -328,18 +328,18 @@ fn pwm(input: &[u8]) -> IResult<&[u8], Result> { let (input, _) = whitespace(input)?; let (input, result) = alt(( |input| { - let (input, ()) = pwm_pid(input)?; - Ok((input, Ok(Command::PwmPid { channel }))) + let (input, ()) = output_pid(input)?; + Ok((input, Ok(Command::OutputPid { channel }))) }, |input| { - let (input, polarity) = pwm_polarity(input)?; - Ok((input, Ok(Command::PwmPolarity { channel, polarity }))) + let (input, polarity) = output_polarity(input)?; + Ok((input, Ok(Command::OutputPolarity { channel, polarity }))) }, |input| { let (input, config) = pwm_setup(input)?; match config { Ok((pin, value)) => - Ok((input, Ok(Command::Pwm { channel, pin, value }))), + Ok((input, Ok(Command::Output { channel, pin, value }))), Err(e) => Ok((input, Err(e))), } @@ -348,7 +348,7 @@ fn pwm(input: &[u8]) -> IResult<&[u8], Result> { end(input)?; Ok((input, result)) }, - value(Ok(Command::Show(ShowCommand::Pwm)), end) + value(Ok(Command::Show(ShowCommand::Output)), end) ))(input) } @@ -593,7 +593,7 @@ fn command(input: &[u8]) -> IResult<&[u8], Result> { value(Ok(Command::Reset), tag("reset")), ipv4, map(report, Ok), - pwm, + output, center_point, pid, steinhart_hart, @@ -685,9 +685,9 @@ mod test { } #[test] - fn parse_pwm_i_set() { - let command = Command::parse(b"pwm 1 i_set 16383"); - assert_eq!(command, Ok(Command::Pwm { + fn parse_output_i_set() { + let command = Command::parse(b"output 1 i_set 16383"); + assert_eq!(command, Ok(Command::Output { channel: 1, pin: PwmPin::ISet, value: 16383.0, @@ -695,26 +695,26 @@ mod test { } #[test] - fn parse_pwm_polarity() { + fn parse_output_polarity() { let command = Command::parse(b"pwm 0 polarity reversed"); - assert_eq!(command, Ok(Command::PwmPolarity { + assert_eq!(command, Ok(Command::OutputPolarity { channel: 0, polarity: Polarity::Reversed, })); } #[test] - fn parse_pwm_pid() { - let command = Command::parse(b"pwm 0 pid"); - assert_eq!(command, Ok(Command::PwmPid { + fn parse_output_pid() { + let command = Command::parse(b"output 0 pid"); + assert_eq!(command, Ok(Command::OutputPid { channel: 0, })); } #[test] - fn parse_pwm_max_i_pos() { - let command = Command::parse(b"pwm 0 max_i_pos 7"); - assert_eq!(command, Ok(Command::Pwm { + fn parse_output_max_i_pos() { + let command = Command::parse(b"output 0 max_i_pos 7"); + assert_eq!(command, Ok(Command::Output { channel: 0, pin: PwmPin::MaxIPos, value: 7.0, @@ -722,9 +722,9 @@ mod test { } #[test] - fn parse_pwm_max_i_neg() { - let command = Command::parse(b"pwm 0 max_i_neg 128"); - assert_eq!(command, Ok(Command::Pwm { + fn parse_output_max_i_neg() { + let command = Command::parse(b"output 0 max_i_neg 128"); + assert_eq!(command, Ok(Command::Output { channel: 0, pin: PwmPin::MaxINeg, value: 128.0, @@ -732,9 +732,9 @@ mod test { } #[test] - fn parse_pwm_max_v() { - let command = Command::parse(b"pwm 0 max_v 32768"); - assert_eq!(command, Ok(Command::Pwm { + fn parse_output_max_v() { + let command = Command::parse(b"output 0 max_v 32768"); + assert_eq!(command, Ok(Command::Output { channel: 0, pin: PwmPin::MaxV, value: 32768.0,