use crate::error::{CaError, CaResult};
use crate::server::record::{FieldDesc, ProcessOutcome, Record};
use crate::types::{DbFieldType, EpicsValue};
pub struct BiRecord {
pub val: u16,
pub rval: i32,
pub oraw: i32, pub mask: i32, pub znam: String,
pub onam: String,
pub zsv: i16,
pub osv: i16,
pub cosv: i16,
pub lalm: u16, pub mlst: u16, pub simm: i16,
pub siml: String,
pub siol: String,
pub sims: i16,
skip_convert: bool,
}
impl Default for BiRecord {
fn default() -> Self {
Self {
val: 0,
rval: 0,
oraw: 0,
mask: 0,
znam: String::new(),
onam: String::new(),
zsv: 0,
osv: 0,
cosv: 0,
lalm: 0,
mlst: 0,
simm: 0,
siml: String::new(),
siol: String::new(),
sims: 0,
skip_convert: false,
}
}
}
impl BiRecord {
pub fn new(val: u16) -> Self {
Self {
val,
..Default::default()
}
}
}
static FIELDS: &[FieldDesc] = &[
FieldDesc {
name: "VAL",
dbf_type: DbFieldType::Enum,
read_only: false,
},
FieldDesc {
name: "RVAL",
dbf_type: DbFieldType::Long,
read_only: false,
},
FieldDesc {
name: "ORAW",
dbf_type: DbFieldType::Long,
read_only: true,
},
FieldDesc {
name: "MASK",
dbf_type: DbFieldType::Long,
read_only: false,
},
FieldDesc {
name: "ZNAM",
dbf_type: DbFieldType::String,
read_only: false,
},
FieldDesc {
name: "ONAM",
dbf_type: DbFieldType::String,
read_only: false,
},
FieldDesc {
name: "ZSV",
dbf_type: DbFieldType::Short,
read_only: false,
},
FieldDesc {
name: "OSV",
dbf_type: DbFieldType::Short,
read_only: false,
},
FieldDesc {
name: "COSV",
dbf_type: DbFieldType::Short,
read_only: false,
},
FieldDesc {
name: "LALM",
dbf_type: DbFieldType::Enum,
read_only: true,
},
FieldDesc {
name: "MLST",
dbf_type: DbFieldType::Enum,
read_only: true,
},
FieldDesc {
name: "SIMM",
dbf_type: DbFieldType::Short,
read_only: false,
},
FieldDesc {
name: "SIML",
dbf_type: DbFieldType::String,
read_only: false,
},
FieldDesc {
name: "SIOL",
dbf_type: DbFieldType::String,
read_only: false,
},
FieldDesc {
name: "SIMS",
dbf_type: DbFieldType::Short,
read_only: false,
},
];
impl Record for BiRecord {
fn record_type(&self) -> &'static str {
"bi"
}
fn init_record(&mut self, pass: u8) -> CaResult<()> {
if pass == 0 {
self.mlst = self.val;
self.lalm = self.val;
self.oraw = self.rval;
}
Ok(())
}
fn process(&mut self) -> CaResult<ProcessOutcome> {
if !self.skip_convert {
if self.rval == 0 {
self.val = 0;
} else {
self.val = 1;
}
}
self.skip_convert = false;
self.oraw = self.rval;
Ok(ProcessOutcome::complete())
}
fn set_device_did_compute(&mut self, did_compute: bool) {
self.skip_convert = did_compute;
}
fn get_field(&self, name: &str) -> Option<EpicsValue> {
match name {
"VAL" => Some(EpicsValue::Enum(self.val)),
"RVAL" => Some(EpicsValue::Long(self.rval)),
"ORAW" => Some(EpicsValue::Long(self.oraw)),
"MASK" => Some(EpicsValue::Long(self.mask)),
"ZNAM" => Some(EpicsValue::String(self.znam.clone())),
"ONAM" => Some(EpicsValue::String(self.onam.clone())),
"ZSV" => Some(EpicsValue::Short(self.zsv)),
"OSV" => Some(EpicsValue::Short(self.osv)),
"COSV" => Some(EpicsValue::Short(self.cosv)),
"LALM" => Some(EpicsValue::Enum(self.lalm)),
"MLST" => Some(EpicsValue::Enum(self.mlst)),
"SIMM" => Some(EpicsValue::Short(self.simm)),
"SIML" => Some(EpicsValue::String(self.siml.clone())),
"SIOL" => Some(EpicsValue::String(self.siol.clone())),
"SIMS" => Some(EpicsValue::Short(self.sims)),
_ => None,
}
}
fn put_field(&mut self, name: &str, value: EpicsValue) -> CaResult<()> {
match name {
"VAL" => match value {
EpicsValue::Enum(v) => {
self.val = v;
Ok(())
}
EpicsValue::Long(v) => {
self.val = v as u16;
Ok(())
}
EpicsValue::Short(v) => {
self.val = v as u16;
Ok(())
}
_ => Err(CaError::TypeMismatch(name.into())),
},
"RVAL" => match value {
EpicsValue::Long(v) => {
self.rval = v;
Ok(())
}
_ => Err(CaError::TypeMismatch(name.into())),
},
"MASK" => match value {
EpicsValue::Long(v) => {
self.mask = v;
Ok(())
}
_ => Err(CaError::TypeMismatch(name.into())),
},
"ZNAM" => match value {
EpicsValue::String(v) => {
self.znam = v;
Ok(())
}
_ => Err(CaError::TypeMismatch(name.into())),
},
"ONAM" => match value {
EpicsValue::String(v) => {
self.onam = v;
Ok(())
}
_ => Err(CaError::TypeMismatch(name.into())),
},
"ZSV" => match value {
EpicsValue::Short(v) => {
self.zsv = v;
Ok(())
}
_ => Err(CaError::TypeMismatch(name.into())),
},
"OSV" => match value {
EpicsValue::Short(v) => {
self.osv = v;
Ok(())
}
_ => Err(CaError::TypeMismatch(name.into())),
},
"COSV" => match value {
EpicsValue::Short(v) => {
self.cosv = v;
Ok(())
}
_ => Err(CaError::TypeMismatch(name.into())),
},
"LALM" => match value {
EpicsValue::Enum(v) => {
self.lalm = v;
Ok(())
}
_ => Err(CaError::TypeMismatch(name.into())),
},
"MLST" => match value {
EpicsValue::Enum(v) => {
self.mlst = v;
Ok(())
}
_ => Err(CaError::TypeMismatch(name.into())),
},
"SIMM" => match value {
EpicsValue::Short(v) => {
self.simm = v;
Ok(())
}
_ => Err(CaError::TypeMismatch(name.into())),
},
"SIML" => match value {
EpicsValue::String(v) => {
self.siml = v;
Ok(())
}
_ => Err(CaError::TypeMismatch(name.into())),
},
"SIOL" => match value {
EpicsValue::String(v) => {
self.siol = v;
Ok(())
}
_ => Err(CaError::TypeMismatch(name.into())),
},
"SIMS" => match value {
EpicsValue::Short(v) => {
self.sims = v;
Ok(())
}
_ => Err(CaError::TypeMismatch(name.into())),
},
_ => Err(CaError::FieldNotFound(name.into())),
}
}
fn field_list(&self) -> &'static [FieldDesc] {
FIELDS
}
fn uses_monitor_deadband(&self) -> bool {
false
}
}