2024-02-16 16:47:17 +08:00
|
|
|
use core::{default, fmt::Debug};
|
2024-02-05 15:14:23 +08:00
|
|
|
use miniconf::{JsonCoreSlash, Tree};
|
2024-02-02 14:07:25 +08:00
|
|
|
use serde::{Deserialize, Serialize};
|
2024-02-05 15:14:23 +08:00
|
|
|
use uom::si::{
|
2024-02-06 15:20:23 +08:00
|
|
|
electric_current::{ampere, milliampere, ElectricCurrent},
|
|
|
|
electric_potential::{volt, ElectricPotential},
|
|
|
|
electrical_resistance::{ElectricalResistance, ohm},
|
|
|
|
f64::ThermodynamicTemperature, thermodynamic_temperature::degree_celsius
|
2024-02-05 15:14:23 +08:00
|
|
|
};
|
2024-02-19 15:08:00 +08:00
|
|
|
use crate::{laser_diode::laser_diode::{
|
|
|
|
LdDrive, StatusReport as LdStatusReport
|
|
|
|
},
|
|
|
|
net::net,
|
|
|
|
thermostat::thermostat::StatusReport as TecStatusReport
|
|
|
|
};
|
2024-02-05 15:14:23 +08:00
|
|
|
use crate::thermostat::thermostat::Thermostat;
|
2024-02-06 15:20:23 +08:00
|
|
|
use crate::thermostat::pid_state::PidSettings::*;
|
2024-02-16 16:47:17 +08:00
|
|
|
use crate::device::dfu;
|
2024-02-02 14:07:25 +08:00
|
|
|
use log::info;
|
2024-02-19 15:08:00 +08:00
|
|
|
use crate::DeviceSettings;
|
2024-02-02 14:07:25 +08:00
|
|
|
|
2024-02-16 16:47:17 +08:00
|
|
|
#[derive(Deserialize, Serialize, Copy, Clone, Default, Debug)]
|
|
|
|
enum DeviceCmd {
|
|
|
|
#[default]
|
|
|
|
Reserved,
|
2024-02-19 15:08:00 +08:00
|
|
|
ReportStatus,
|
|
|
|
Dfu,
|
2024-02-16 16:47:17 +08:00
|
|
|
}
|
|
|
|
|
2024-02-02 14:07:25 +08:00
|
|
|
#[derive(Deserialize, Serialize, Copy, Clone, Default, Debug)]
|
|
|
|
enum LdCmdEnum {
|
|
|
|
#[default]
|
|
|
|
Reserved,
|
|
|
|
// LD Drive Related
|
|
|
|
PowerUp,
|
|
|
|
PowerDown,
|
|
|
|
LdTermsShort,
|
|
|
|
LdTermsOpen,
|
|
|
|
SetI,
|
|
|
|
SetISoftLimit,
|
|
|
|
// PD Mon Related
|
|
|
|
SetPdResponsitivity,
|
|
|
|
SetPdDarkCurrent,
|
|
|
|
SetPdILimit,
|
|
|
|
SetLdPwrLimit,
|
|
|
|
ClearAlarmStatus,
|
|
|
|
// Report Related
|
|
|
|
GetModInTermStatus,
|
|
|
|
GetLdStatus,
|
|
|
|
GetAlramStatus,
|
|
|
|
}
|
|
|
|
|
2024-02-05 15:14:23 +08:00
|
|
|
#[derive(Deserialize, Serialize, Copy, Clone, Default, Debug)]
|
|
|
|
enum ThermostatCmdEnum {
|
|
|
|
#[default]
|
|
|
|
Reserved,
|
|
|
|
PowerUp,
|
|
|
|
PowerDown,
|
|
|
|
// TEC
|
|
|
|
SetTecMaxV,
|
|
|
|
SetTecMaxIPos,
|
|
|
|
SetTecMaxINeg,
|
|
|
|
SetTecIOut, // Constant Current Mode
|
2024-02-06 15:20:23 +08:00
|
|
|
SetTemperatureSetpoint,
|
2024-02-05 15:14:23 +08:00
|
|
|
// PID
|
2024-02-15 10:34:02 +08:00
|
|
|
SetPidEngage,
|
|
|
|
SetPidDisEngage,
|
2024-02-05 15:14:23 +08:00
|
|
|
SetPidKp,
|
|
|
|
SetPidKi,
|
|
|
|
SetPidKd,
|
|
|
|
SetPidOutMin,
|
|
|
|
SetPidOutMax,
|
|
|
|
SetPidUpdateInterval, // Update Interval is set based on the sampling rate of ADC
|
|
|
|
// Steinhart-Hart Equation
|
|
|
|
SetShT0,
|
|
|
|
SetShR0,
|
|
|
|
SetShBeta,
|
|
|
|
// Report Related
|
|
|
|
GetTecStatus,
|
|
|
|
GetPidStatus,
|
|
|
|
GetShParams,
|
|
|
|
}
|
|
|
|
|
2024-02-02 14:07:25 +08:00
|
|
|
#[derive(Deserialize, Serialize, Copy, Clone, Debug, Default, Tree)]
|
|
|
|
pub struct CmdJsonObj{
|
2024-02-05 15:14:23 +08:00
|
|
|
laser_diode_cmd: Option<LdCmdEnum>,
|
|
|
|
thermostat_cmd: Option<ThermostatCmdEnum>,
|
2024-02-16 16:47:17 +08:00
|
|
|
device_cmd: Option<DeviceCmd>,
|
2024-02-19 15:08:00 +08:00
|
|
|
data_bool: Option<bool>,
|
2024-02-02 14:07:25 +08:00
|
|
|
data_f32: Option<f32>,
|
|
|
|
data_f64: Option<f64>,
|
|
|
|
}
|
|
|
|
#[derive(Deserialize, Serialize, Copy, Clone, Debug, Default, Tree)]
|
|
|
|
pub struct Cmd {
|
|
|
|
json: CmdJsonObj
|
|
|
|
}
|
|
|
|
|
2024-02-19 15:08:00 +08:00
|
|
|
#[derive(Deserialize, Serialize, Copy, Clone, Debug, Tree)]
|
|
|
|
pub struct TecStatusReportStruct {
|
|
|
|
json: TecStatusReport
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Deserialize, Serialize, Copy, Clone, Debug, Tree)]
|
|
|
|
pub struct LaserStatusReportStruct {
|
|
|
|
json: LdStatusReport
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn send_ld_readings(buffer: &mut [u8], laser: &mut LdDrive){
|
|
|
|
let status_report = LaserStatusReportStruct {
|
|
|
|
json: laser.get_status_report()
|
|
|
|
};
|
|
|
|
let num_bytes = status_report.get_json("/json", buffer).unwrap();
|
|
|
|
net::eth_send(buffer, num_bytes);
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn send_tec_readings(buffer: &mut [u8], tec: &mut Thermostat){
|
|
|
|
let status_report = TecStatusReportStruct {
|
|
|
|
json: tec.get_status_report()
|
|
|
|
};
|
|
|
|
let num_bytes = status_report.get_json("/json", buffer).unwrap();
|
|
|
|
net::eth_send(buffer, num_bytes);
|
2024-02-15 10:34:02 +08:00
|
|
|
}
|
|
|
|
|
2024-02-19 15:08:00 +08:00
|
|
|
pub fn execute_cmd(buffer: &mut [u8], buffer_size: usize, mut laser: LdDrive, mut tec: Thermostat, mut device_settings: DeviceSettings)->(LdDrive, Thermostat, bool, DeviceSettings){
|
2024-02-16 16:47:17 +08:00
|
|
|
let mut should_reset = false;
|
|
|
|
|
2024-02-02 14:07:25 +08:00
|
|
|
let mut cmd = Cmd {
|
|
|
|
json: CmdJsonObj::default()
|
|
|
|
};
|
|
|
|
match cmd.set_json("/json", &buffer[0..buffer_size]){
|
|
|
|
Ok(_) => {
|
2024-02-06 15:20:23 +08:00
|
|
|
info!("############ Laser Diode Command Received {:?}", cmd.json.laser_diode_cmd);
|
|
|
|
info!("############ Thermostat Command Received {:?}", cmd.json.thermostat_cmd);
|
2024-02-16 16:47:17 +08:00
|
|
|
info!("############ Device Command Received {:?}", cmd.json.device_cmd);
|
|
|
|
|
|
|
|
match cmd.json.device_cmd {
|
|
|
|
Some(DeviceCmd::Dfu) => {
|
|
|
|
unsafe {
|
|
|
|
dfu::set_dfu_trigger();
|
|
|
|
}
|
|
|
|
should_reset = true;
|
|
|
|
}
|
2024-02-19 15:08:00 +08:00
|
|
|
Some(DeviceCmd::ReportStatus) => {
|
|
|
|
match cmd.json.data_bool{
|
|
|
|
Some(val) => {
|
|
|
|
device_settings.report_readings = val;
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
info!("Wrong Data type is received")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-02-16 16:47:17 +08:00
|
|
|
None => { /* Do Nothing */}
|
|
|
|
_ => {
|
|
|
|
info!("Unimplemented Command")
|
|
|
|
}
|
|
|
|
}
|
2024-02-02 14:07:25 +08:00
|
|
|
|
|
|
|
match cmd.json.laser_diode_cmd {
|
2024-02-05 15:14:23 +08:00
|
|
|
Some(LdCmdEnum::PowerUp) => {
|
2024-02-02 14:07:25 +08:00
|
|
|
laser.power_up()
|
|
|
|
}
|
2024-02-05 15:14:23 +08:00
|
|
|
Some(LdCmdEnum::PowerDown) => {
|
2024-02-02 14:07:25 +08:00
|
|
|
laser.power_down()
|
|
|
|
}
|
2024-02-05 15:14:23 +08:00
|
|
|
Some(LdCmdEnum::LdTermsShort) => {
|
2024-02-02 14:07:25 +08:00
|
|
|
laser.ld_short();
|
|
|
|
}
|
2024-02-05 15:14:23 +08:00
|
|
|
Some(LdCmdEnum::LdTermsOpen) => {
|
2024-02-02 14:07:25 +08:00
|
|
|
laser.ld_open();
|
|
|
|
}
|
2024-02-05 15:14:23 +08:00
|
|
|
Some(LdCmdEnum::SetI) => {
|
2024-02-02 14:07:25 +08:00
|
|
|
match cmd.json.data_f64 {
|
|
|
|
Some(val) => {
|
|
|
|
laser.ld_set_i(ElectricCurrent::new::<milliampere>(val));
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
info!("Wrong Data type is received")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-02-05 15:14:23 +08:00
|
|
|
Some(LdCmdEnum::SetISoftLimit) => {
|
2024-02-02 14:07:25 +08:00
|
|
|
match cmd.json.data_f64 {
|
|
|
|
Some(val) => {
|
|
|
|
laser.set_ld_drive_current_limit(ElectricCurrent::new::<milliampere>(val))
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
info!("Wrong Data type is received")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-02-05 15:14:23 +08:00
|
|
|
Some(LdCmdEnum::SetPdResponsitivity) => {
|
2024-02-02 14:07:25 +08:00
|
|
|
info!("Not supported Yet")
|
|
|
|
}
|
2024-02-05 15:14:23 +08:00
|
|
|
Some(LdCmdEnum::SetPdDarkCurrent) => {
|
2024-02-02 14:07:25 +08:00
|
|
|
info!("Not supported Yet")
|
|
|
|
}
|
2024-02-05 15:14:23 +08:00
|
|
|
Some(LdCmdEnum::SetPdILimit) => {
|
2024-02-02 14:07:25 +08:00
|
|
|
match cmd.json.data_f64 {
|
|
|
|
Some(val) => {
|
|
|
|
laser.set_pd_i_limit(ElectricCurrent::new::<milliampere>(val))
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
info!("Wrong Data type is received")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-02-05 15:14:23 +08:00
|
|
|
Some(LdCmdEnum::SetLdPwrLimit) => {
|
2024-02-02 14:07:25 +08:00
|
|
|
info!("Not supported Yet")
|
|
|
|
}
|
2024-02-05 15:14:23 +08:00
|
|
|
Some(LdCmdEnum::ClearAlarmStatus) => {
|
2024-02-02 14:07:25 +08:00
|
|
|
laser.pd_mon_clear_alarm()
|
|
|
|
}
|
2024-02-05 15:14:23 +08:00
|
|
|
Some(LdCmdEnum::GetModInTermStatus) => {
|
2024-02-02 14:07:25 +08:00
|
|
|
info!("Not supported Yet")
|
|
|
|
}
|
2024-02-05 15:14:23 +08:00
|
|
|
Some(LdCmdEnum::GetLdStatus) => {
|
2024-02-19 15:08:00 +08:00
|
|
|
send_ld_readings(buffer, &mut laser);
|
2024-02-02 14:07:25 +08:00
|
|
|
}
|
2024-02-05 15:14:23 +08:00
|
|
|
Some(LdCmdEnum::GetAlramStatus) => {
|
2024-02-02 14:07:25 +08:00
|
|
|
info!("Not supported Yet")
|
|
|
|
}
|
2024-02-05 15:14:23 +08:00
|
|
|
None => { /* Do Nothing*/ }
|
2024-02-02 14:07:25 +08:00
|
|
|
_ => {
|
|
|
|
info!("Unimplemented Command")
|
|
|
|
}
|
|
|
|
}
|
2024-02-05 15:14:23 +08:00
|
|
|
|
|
|
|
match cmd.json.thermostat_cmd {
|
|
|
|
Some(ThermostatCmdEnum::PowerUp) => {
|
2024-02-15 10:34:02 +08:00
|
|
|
tec.power_up()
|
2024-02-05 15:14:23 +08:00
|
|
|
}
|
|
|
|
Some(ThermostatCmdEnum::PowerDown) => {
|
2024-02-15 10:34:02 +08:00
|
|
|
tec.power_down()
|
2024-02-05 15:14:23 +08:00
|
|
|
}
|
|
|
|
Some(ThermostatCmdEnum::SetTecMaxV) => {
|
|
|
|
match cmd.json.data_f64 {
|
|
|
|
Some(val) => {
|
|
|
|
tec.set_max_v(ElectricPotential::new::<volt>(val));
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
info!("Wrong Data type is received")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Some(ThermostatCmdEnum::SetTecMaxIPos) => {
|
|
|
|
match cmd.json.data_f64 {
|
|
|
|
Some(val) => {
|
|
|
|
tec.set_max_i_pos(ElectricCurrent::new::<ampere>(val));
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
info!("Wrong Data type is received")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Some(ThermostatCmdEnum::SetTecMaxINeg) => {
|
|
|
|
match cmd.json.data_f64 {
|
|
|
|
Some(val) => {
|
|
|
|
tec.set_max_i_pos(ElectricCurrent::new::<milliampere>(val));
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
info!("Wrong Data type is received")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Some(ThermostatCmdEnum::SetTecIOut) => {
|
|
|
|
match cmd.json.data_f64 {
|
|
|
|
Some(val) => {
|
|
|
|
tec.set_i(ElectricCurrent::new::<milliampere>(val));
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
info!("Wrong Data type is received")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-02-06 15:20:23 +08:00
|
|
|
Some(ThermostatCmdEnum::SetTemperatureSetpoint) => {
|
|
|
|
match cmd.json.data_f64 {
|
|
|
|
Some(val) => {
|
|
|
|
tec.set_temperature_setpoint(ThermodynamicTemperature::new::<degree_celsius>(val));
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
info!("Wrong Data type is received")
|
|
|
|
}
|
|
|
|
}
|
2024-02-05 15:14:23 +08:00
|
|
|
}
|
2024-02-15 10:34:02 +08:00
|
|
|
Some(ThermostatCmdEnum::SetPidEngage) => {
|
|
|
|
tec.set_pid_engaged(true);
|
|
|
|
}
|
|
|
|
Some(ThermostatCmdEnum::SetPidDisEngage) => {
|
|
|
|
tec.set_pid_engaged(false);
|
|
|
|
}
|
2024-02-05 15:14:23 +08:00
|
|
|
Some(ThermostatCmdEnum::SetPidKp) => {
|
2024-02-06 15:20:23 +08:00
|
|
|
match cmd.json.data_f64 {
|
|
|
|
Some(val) => {
|
|
|
|
tec.set_pid(Kp, val);
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
info!("Wrong Data type is received")
|
|
|
|
}
|
|
|
|
}
|
2024-02-05 15:14:23 +08:00
|
|
|
}
|
|
|
|
Some(ThermostatCmdEnum::SetPidKi) => {
|
2024-02-06 15:20:23 +08:00
|
|
|
match cmd.json.data_f64 {
|
|
|
|
Some(val) => {
|
|
|
|
tec.set_pid(Ki, val);
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
info!("Wrong Data type is received")
|
|
|
|
}
|
|
|
|
}
|
2024-02-05 15:14:23 +08:00
|
|
|
}
|
|
|
|
Some(ThermostatCmdEnum::SetPidKd) => {
|
2024-02-06 15:20:23 +08:00
|
|
|
match cmd.json.data_f64 {
|
|
|
|
Some(val) => {
|
|
|
|
tec.set_pid(Kd, val);
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
info!("Wrong Data type is received")
|
|
|
|
}
|
|
|
|
}
|
2024-02-05 15:14:23 +08:00
|
|
|
}
|
|
|
|
Some(ThermostatCmdEnum::SetPidOutMin) => {
|
2024-02-06 15:20:23 +08:00
|
|
|
match cmd.json.data_f64 {
|
|
|
|
Some(val) => {
|
|
|
|
tec.set_pid(Min, val);
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
info!("Wrong Data type is received")
|
|
|
|
}
|
|
|
|
}
|
2024-02-05 15:14:23 +08:00
|
|
|
}
|
|
|
|
Some(ThermostatCmdEnum::SetPidOutMax) => {
|
2024-02-06 15:20:23 +08:00
|
|
|
match cmd.json.data_f64 {
|
|
|
|
Some(val) => {
|
|
|
|
tec.set_pid(Max, val);
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
info!("Wrong Data type is received")
|
|
|
|
}
|
|
|
|
}
|
2024-02-05 15:14:23 +08:00
|
|
|
}
|
|
|
|
Some(ThermostatCmdEnum::SetPidUpdateInterval) => {
|
|
|
|
info!("Not supported Yet")
|
|
|
|
}
|
|
|
|
Some(ThermostatCmdEnum::SetShT0) => {
|
2024-02-06 15:20:23 +08:00
|
|
|
match cmd.json.data_f64 {
|
|
|
|
Some(val) => {
|
|
|
|
tec.set_sh_t0(ThermodynamicTemperature::new::<degree_celsius>(val));
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
info!("Wrong Data type is received")
|
|
|
|
}
|
|
|
|
}
|
2024-02-05 15:14:23 +08:00
|
|
|
}
|
|
|
|
Some(ThermostatCmdEnum::SetShR0) => {
|
2024-02-06 15:20:23 +08:00
|
|
|
match cmd.json.data_f64 {
|
|
|
|
Some(val) => {
|
|
|
|
tec.set_sh_r0(ElectricalResistance::new::<ohm>(val));
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
info!("Wrong Data type is received")
|
|
|
|
}
|
|
|
|
}
|
2024-02-05 15:14:23 +08:00
|
|
|
}
|
|
|
|
Some(ThermostatCmdEnum::SetShBeta) => {
|
2024-02-06 15:20:23 +08:00
|
|
|
match cmd.json.data_f64 {
|
|
|
|
Some(val) => {
|
|
|
|
tec.set_sh_beta(val);
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
info!("Wrong Data type is received")
|
|
|
|
}
|
|
|
|
}
|
2024-02-05 15:14:23 +08:00
|
|
|
}
|
|
|
|
Some(ThermostatCmdEnum::GetTecStatus) => {
|
2024-02-19 15:08:00 +08:00
|
|
|
send_tec_readings(buffer, &mut tec);
|
2024-02-05 15:14:23 +08:00
|
|
|
}
|
|
|
|
Some(ThermostatCmdEnum::GetPidStatus) => {
|
|
|
|
info!("Not supported Yet")
|
|
|
|
}
|
|
|
|
Some(ThermostatCmdEnum::GetShParams) => {
|
|
|
|
info!("Not supported Yet")
|
|
|
|
}
|
|
|
|
None => { /* Do Nothing*/ }
|
|
|
|
_ => {
|
|
|
|
info!("Unimplemented Command")
|
|
|
|
}
|
|
|
|
}
|
2024-02-02 14:07:25 +08:00
|
|
|
}
|
|
|
|
Err(err) => {
|
|
|
|
info!("Invalid Command: {:?}", err);
|
|
|
|
}
|
|
|
|
}
|
2024-02-19 15:08:00 +08:00
|
|
|
(laser, tec, should_reset, device_settings)
|
2024-02-02 14:07:25 +08:00
|
|
|
}
|