use crate::dynamic_diag::DynamicDiagSession;
use crate::obd2::{
Distance, ObdEnumValue, ObdUnitType, ObdValue, Pressure, Speed, Temperature, Time,
};
use crate::{DiagError, DiagServerResult};
use automotive_diag::obd2::{
CommandedSecondaryAirStatusByte, DataPidByte, FuelSystemStatusByte, FuelTypeCodingByte,
ObdStandardByte,
};
use automotive_diag::ByteWrapper::Standard;
#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
pub struct DataPidWrapper(DataPidByte);
impl DataPidWrapper {
fn request_ecu(
&self,
server: &DynamicDiagSession,
ff: Option<u16>,
min_length: usize,
) -> DiagServerResult<Vec<u8>> {
let req = match ff {
None => vec![0x01, self.0.into()],
Some(ff_id) => vec![0x02, self.0.into(), (ff_id >> 8) as u8, ff_id as u8],
};
let mut r = server.send_byte_array_with_response(&req, None)?;
r.drain(0..2);
if r.len() < min_length {
return Err(DiagError::InvalidResponseLength);
}
Ok(r)
}
fn get_percentage_1_byte(
&self,
server: &DynamicDiagSession,
ff: Option<u16>,
name: &str,
) -> DiagServerResult<Vec<ObdValue>> {
Ok(vec![ObdValue::new(
name,
ObdUnitType::Percent(self.request_ecu(server, ff, 1)?[0] as f32 * (100.0 / 255.0)),
)])
}
#[allow(clippy::excessive_precision)]
pub(crate) fn get_value(
&self,
server: &DynamicDiagSession,
ff: Option<u16>,
) -> DiagServerResult<Vec<ObdValue>> {
use automotive_diag::obd2::DataPid::*;
match self.0 {
Standard(PidSupport0120) => Ok(vec![ObdValue::new(
"PID support 01-20",
ObdUnitType::ByteArray(self.request_ecu(server, ff, 4)?),
)]),
Standard(StatusSinceDTCCleared) => Err(DiagError::NotImplemented(
"Status since DTC Cleared unimplemented".into(),
)),
Standard(FreezeDTC) => {
Err(DiagError::NotImplemented("Freeze DTC unimplemented".into()))
}
Standard(FuelSystemStatus) => Ok(self
.request_ecu(server, ff, 1)?
.iter()
.enumerate()
.map(|(idx, byte)| {
ObdValue::new(
format!("Fuel system status {}", idx + 1),
ObdUnitType::Encoded(ObdEnumValue::FuelSystemStatus(
FuelSystemStatusByte::from(*byte),
)),
)
})
.collect()),
Standard(CalculatedEngineLoad) => {
self.get_percentage_1_byte(server, ff, "Calculated engine load")
}
Standard(EngineCoolantTemp) => Ok(self
.request_ecu(server, ff, 1)?
.iter()
.map(|x| {
ObdValue::new(
"Engine coolant temperature",
ObdUnitType::Temperature(Temperature::from_celsius(*x as f32 - 40.0)),
)
})
.collect()),
Standard(ShortTermFuelTrimBank1) => Ok(vec![ObdValue::new(
"Short term fuel trim - Bank 1",
ObdUnitType::Percent((self.request_ecu(server, ff, 1)?[0] as f32 / 1.28) - 100.0),
)]),
Standard(LongTermFuelTrimBank1) => Ok(vec![ObdValue::new(
"Long term fuel trim - Bank 1",
ObdUnitType::Percent((self.request_ecu(server, ff, 1)?[0] as f32 / 1.28) - 100.0),
)]),
Standard(ShortTermFuelTrimBank2) => Ok(vec![ObdValue::new(
"Short term fuel trim - Bank 2",
ObdUnitType::Percent((self.request_ecu(server, ff, 1)?[0] as f32 / 1.28) - 100.0),
)]),
Standard(LongTermFuelTrimBank2) => Ok(vec![ObdValue::new(
"Long term fuel trim - Bank 2",
ObdUnitType::Percent((self.request_ecu(server, ff, 1)?[0] as f32 / 1.28) - 100.0),
)]),
Standard(FuelPressureGauge) => Ok(vec![ObdValue::new(
"Fuel pressure (gauge pressure)",
ObdUnitType::Pressure(Pressure::from_kilo_pascal(
self.request_ecu(server, ff, 1)?[0] as f32 * 3.0,
)),
)]),
Standard(IntakeManifoldAbsPressure) => Ok(vec![ObdValue::new(
"Intake manifold absolute pressure",
ObdUnitType::Pressure(Pressure::from_kilo_pascal(
self.request_ecu(server, ff, 1)?[0] as f32,
)),
)]),
Standard(EngineSpeed) => {
let r = self.request_ecu(server, ff, 2)?;
Ok(vec![ObdValue::new(
"Engine speed",
ObdUnitType::Rpm(((r[0] as u32) << 8) | r[1] as u32),
)])
}
Standard(VehicleSpeed) => Ok(vec![ObdValue::new(
"Vehicle speed",
ObdUnitType::Speed(Speed::from_kmh(self.request_ecu(server, ff, 1)?[0] as f32)),
)]),
Standard(TimingAdvance) => Ok(vec![ObdValue::new(
"Timing advance before TDC (degrees)",
ObdUnitType::Raw(self.request_ecu(server, ff, 1)?[0] as f32 - 64.0),
)]),
Standard(IntakeAirTemperature) => Ok(vec![ObdValue::new(
"Intake air temperature",
ObdUnitType::Temperature(Temperature::from_celsius(
self.request_ecu(server, ff, 1)?[0] as f32 - 40.0,
)),
)]),
Standard(MassAirFlow) => {
let s = self.request_ecu(server, ff, 2)?;
Ok(vec![ObdValue::new(
"Mass air flow sensor rate (Grames/sec)",
ObdUnitType::Raw(((s[0] as u32) << 8 | s[1] as u32) as f32 / 100.0),
)])
}
Standard(ThrottlePosition) => {
self.get_percentage_1_byte(server, ff, "Throttle position")
}
Standard(CommandedSecondaryAirStatus) => Ok(vec![ObdValue::new(
"Commanded secondary air status",
ObdUnitType::Encoded(ObdEnumValue::CommandedAirStatus(
CommandedSecondaryAirStatusByte::from(self.request_ecu(server, ff, 1)?[0]),
)),
)]),
Standard(O2SensorsPresent2Banks) => Ok(vec![ObdValue::new(
"Oxygen sensors present in 2 banks",
ObdUnitType::ByteArray(self.request_ecu(server, ff, 1)?),
)]),
Standard(OxygenSensor1) => {
let r = self.request_ecu(server, ff, 2)?;
Ok(vec![
ObdValue::new(
"Oxygen sensor 1 voltage",
ObdUnitType::Volts(r[0] as f32 / 200.0),
),
ObdValue::new(
"Oxygen sensor 1 short term fuel trim",
ObdUnitType::Percent((r[1] as f32 / 1.28) - 100.0),
),
])
}
Standard(OxygenSensor2) => {
let r = self.request_ecu(server, ff, 2)?;
Ok(vec![
ObdValue::new(
"Oxygen sensor 2 voltage",
ObdUnitType::Volts(r[0] as f32 / 200.0),
),
ObdValue::new(
"Oxygen sensor 2 short term fuel trim",
ObdUnitType::Percent((r[1] as f32 / 1.28) - 100.0),
),
])
}
Standard(OxygenSensor3) => {
let r = self.request_ecu(server, ff, 2)?;
Ok(vec![
ObdValue::new(
"Oxygen sensor 3 voltage",
ObdUnitType::Volts(r[0] as f32 / 200.0),
),
ObdValue::new(
"Oxygen sensor 3 short term fuel trim",
ObdUnitType::Percent((r[1] as f32 / 1.28) - 100.0),
),
])
}
Standard(OxygenSensor4) => {
let r = self.request_ecu(server, ff, 2)?;
Ok(vec![
ObdValue::new(
"Oxygen sensor 4 voltage",
ObdUnitType::Volts(r[0] as f32 / 200.0),
),
ObdValue::new(
"Oxygen sensor 4 short term fuel trim",
ObdUnitType::Percent((r[1] as f32 / 1.28) - 100.0),
),
])
}
Standard(OxygenSensor5) => {
let r = self.request_ecu(server, ff, 2)?;
Ok(vec![
ObdValue::new(
"Oxygen sensor 5 voltage",
ObdUnitType::Volts(r[0] as f32 / 200.0),
),
ObdValue::new(
"Oxygen sensor 5 short term fuel trim",
ObdUnitType::Percent((r[1] as f32 / 1.28) - 100.0),
),
])
}
Standard(OxygenSensor6) => {
let r = self.request_ecu(server, ff, 2)?;
Ok(vec![
ObdValue::new(
"Oxygen sensor 6 voltage",
ObdUnitType::Volts(r[0] as f32 / 200.0),
),
ObdValue::new(
"Oxygen sensor 6 short term fuel trim",
ObdUnitType::Percent((r[1] as f32 / 1.28) - 100.0),
),
])
}
Standard(OxygenSensor7) => {
let r = self.request_ecu(server, ff, 2)?;
Ok(vec![
ObdValue::new(
"Oxygen sensor 7 voltage",
ObdUnitType::Volts(r[0] as f32 / 200.0),
),
ObdValue::new(
"Oxygen sensor 7 short term fuel trim",
ObdUnitType::Percent((r[1] as f32 / 1.28) - 100.0),
),
])
}
Standard(OxygenSensor8) => {
let r = self.request_ecu(server, ff, 2)?;
Ok(vec![
ObdValue::new(
"Oxygen sensor 8 voltage",
ObdUnitType::Volts(r[0] as f32 / 200.0),
),
ObdValue::new(
"Oxygen sensor 8 short term fuel trim",
ObdUnitType::Percent((r[1] as f32 / 1.28) - 100.0),
),
])
}
Standard(ObdStandard) => Ok(vec![ObdValue::new(
"OBD Standard",
ObdUnitType::Encoded(ObdEnumValue::ObdStandard(ObdStandardByte::from(
self.request_ecu(server, ff, 1)?[0],
))),
)]),
Standard(O2SensorsPresent4Banks) => Ok(vec![ObdValue::new(
"Oxygen sensors present in 4 banks",
ObdUnitType::ByteArray(self.request_ecu(server, ff, 1)?),
)]),
Standard(RuntimeSinceStart) => {
let r = self.request_ecu(server, ff, 2)?;
Ok(vec![ObdValue::new(
"Runtime since engine start",
ObdUnitType::Time(Time::from_seconds(
((r[0] as u32) << 8 | r[1] as u32) as f32,
)),
)])
}
Standard(PidSupport2140) => Ok(vec![ObdValue::new(
"PID support 21-40",
ObdUnitType::ByteArray(self.request_ecu(server, ff, 4)?),
)]),
Standard(MILRuntime) => {
let r = self.request_ecu(server, ff, 2)?;
Ok(vec![ObdValue::new(
"Distance travelled with MIL on",
ObdUnitType::Distance(Distance::from_kilometers(
((r[0] as u32) << 8 | r[1] as u32) as f32,
)),
)])
}
Standard(FuelRailPressure) => {
let r = self.request_ecu(server, ff, 2)?;
Ok(vec![ObdValue::new(
"Fuel rail pressure (Relative to manifold vacuum)",
ObdUnitType::Pressure(Pressure::from_kilo_pascal(
((r[0] as u32) << 8 | r[1] as u32) as f32 * 0.079,
)),
)])
}
Standard(FuelRailGaugePressure) => {
let r = self.request_ecu(server, ff, 2)?;
Ok(vec![ObdValue::new(
"Fuel rail gauge pressure",
ObdUnitType::Pressure(Pressure::from_kilo_pascal(
((r[0] as u32) << 8 | r[1] as u32) as f32 * 10.0,
)),
)])
}
Standard(OxygenSensor1LambdaVoltage) => {
let r = self.request_ecu(server, ff, 4)?;
Ok(vec![
ObdValue::new(
"Oxygen sensor 1 Lambda",
ObdUnitType::Raw(
((r[0] as u32) << 8 | r[1] as u32) as f32 * 0.000030517578125,
),
),
ObdValue::new(
"Oxygen sensor 1 voltage",
ObdUnitType::Volts(
((r[2] as u32) << 8 | r[3] as u32) as f32 * 0.0001220703125,
),
),
])
}
Standard(OxygenSensor2LambdaVoltage) => {
let r = self.request_ecu(server, ff, 4)?;
Ok(vec![
ObdValue::new(
"Oxygen sensor 2 Lambda",
ObdUnitType::Raw(
((r[0] as u32) << 8 | r[1] as u32) as f32 * 0.000030517578125,
),
),
ObdValue::new(
"Oxygen sensor 2 voltage",
ObdUnitType::Volts(
((r[2] as u32) << 8 | r[3] as u32) as f32 * 0.000_1220703125,
),
),
])
}
Standard(OxygenSensor3LambdaVoltage) => {
let r = self.request_ecu(server, ff, 4)?;
Ok(vec![
ObdValue::new(
"Oxygen sensor 3 Lambda",
ObdUnitType::Raw(
((r[0] as u32) << 8 | r[1] as u32) as f32 * 0.000030517578125,
),
),
ObdValue::new(
"Oxygen sensor 3 voltage",
ObdUnitType::Volts(
((r[2] as u32) << 8 | r[3] as u32) as f32 * 0.0001220703125,
),
),
])
}
Standard(OxygenSensor4LambdaVoltage) => {
let r = self.request_ecu(server, ff, 4)?;
Ok(vec![
ObdValue::new(
"Oxygen sensor 4 Lambda",
ObdUnitType::Raw(
((r[0] as u32) << 8 | r[1] as u32) as f32 * 0.000030517578125,
),
),
ObdValue::new(
"Oxygen sensor 4 voltage",
ObdUnitType::Volts(
((r[2] as u32) << 8 | r[3] as u32) as f32 * 0.0001220703125,
),
),
])
}
Standard(OxygenSensor5LambdaVoltage) => {
let r = self.request_ecu(server, ff, 4)?;
Ok(vec![
ObdValue::new(
"Oxygen sensor 5 Lambda",
ObdUnitType::Raw(
((r[0] as u32) << 8 | r[1] as u32) as f32 * 0.000030517578125,
),
),
ObdValue::new(
"Oxygen sensor 5 voltage",
ObdUnitType::Volts(
((r[2] as u32) << 8 | r[3] as u32) as f32 * 0.0001220703125,
),
),
])
}
Standard(OxygenSensor6LambdaVoltage) => {
let r = self.request_ecu(server, ff, 4)?;
Ok(vec![
ObdValue::new(
"Oxygen sensor 6 Lambda",
ObdUnitType::Raw(
((r[0] as u32) << 8 | r[1] as u32) as f32 * 0.000030517578125,
),
),
ObdValue::new(
"Oxygen sensor 6 voltage",
ObdUnitType::Volts(
((r[2] as u32) << 8 | r[3] as u32) as f32 * 0.0001220703125,
),
),
])
}
Standard(OxygenSensor7LambdaVoltage) => {
let r = self.request_ecu(server, ff, 4)?;
Ok(vec![
ObdValue::new(
"Oxygen sensor 7 Lambda",
ObdUnitType::Raw(
((r[0] as u32) << 8 | r[1] as u32) as f32 * 0.000030517578125,
),
),
ObdValue::new(
"Oxygen sensor 7 voltage",
ObdUnitType::Volts(
((r[2] as u32) << 8 | r[3] as u32) as f32 * 0.0001220703125,
),
),
])
}
Standard(OxygenSensor8LambdaVoltage) => {
let r = self.request_ecu(server, ff, 4)?;
Ok(vec![
ObdValue::new(
"Oxygen sensor 8 Lambda",
ObdUnitType::Raw(
((r[0] as u32) << 8 | r[1] as u32) as f32 * 0.000030517578125,
),
),
ObdValue::new(
"Oxygen sensor 8 voltage",
ObdUnitType::Volts(
((r[2] as u32) << 8 | r[3] as u32) as f32 * 0.0001220703125,
),
),
])
}
Standard(CommandedEGR) => self.get_percentage_1_byte(server, ff, "Commanded EGR"),
Standard(EGRError) => Ok(vec![ObdValue::new(
"EGR Error",
ObdUnitType::Percent(
self.request_ecu(server, ff, 1)?[0] as f32 * (100.0 / 128.0) - 100.0,
),
)]),
Standard(CommandedEvapPurge) => {
self.get_percentage_1_byte(server, ff, "Commanded evaporative purge")
}
Standard(FuelTankLevelInput) => {
self.get_percentage_1_byte(server, ff, "Fuel tank level input")
}
Standard(WarmupsSinceCodesCleared) => Ok(vec![ObdValue::new(
"Warm-ups since codes cleared",
ObdUnitType::Raw(self.request_ecu(server, ff, 1)?[0] as f32),
)]),
Standard(DistanceTraveledSinceCodesCleared) => {
let r = self.request_ecu(server, ff, 2)?;
Ok(vec![ObdValue::new(
"Distance traveled since codes cleared",
ObdUnitType::Distance(Distance::from_kilometers(
(((r[0] as u32) << 8) | r[1] as u32) as f32,
)),
)])
}
Standard(EvapSystemVaporPressure) => {
let r: Vec<i32> = self
.request_ecu(server, ff, 2)?
.iter()
.map(|x| *x as i32)
.collect();
Ok(vec![ObdValue::new(
"Evaporative System Vapor Pressure",
ObdUnitType::Pressure(Pressure::from_kilo_pascal(
(r[0] << 8 | r[1]) as f32 / 4000.0,
)),
)])
}
Standard(AbsBarometricPressure) => Ok(vec![ObdValue::new(
"Absolute Barometric Pressure",
ObdUnitType::Pressure(Pressure::from_kilo_pascal(
self.request_ecu(server, ff, 1)?[0] as f32,
)),
)]),
Standard(OxygenSensor1LambdaCurrent) => {
let r: Vec<u32> = self
.request_ecu(server, ff, 4)?
.iter()
.map(|x| *x as u32)
.collect();
Ok(vec![
ObdValue::new(
"Oxygen sensor 1 Lambda",
ObdUnitType::Raw((r[0] << 8 | r[1]) as f32 * (2.0 / 65536.0)),
),
ObdValue::new(
"Oxygen sensor 1 Current",
ObdUnitType::Raw(((r[2] << 8 | r[3]) as f32 / 256.0) - 128.0),
),
])
}
Standard(OxygenSensor2LambdaCurrent) => {
let r: Vec<u32> = self
.request_ecu(server, ff, 4)?
.iter()
.map(|x| *x as u32)
.collect();
Ok(vec![
ObdValue::new(
"Oxygen sensor 2 Lambda",
ObdUnitType::Raw((r[0] << 8 | r[1]) as f32 * (2.0 / 65536.0)),
),
ObdValue::new(
"Oxygen sensor 2 Current",
ObdUnitType::Raw(((r[2] << 8 | r[3]) as f32 / 256.0) - 128.0),
),
])
}
Standard(OxygenSensor3LambdaCurrent) => {
let r: Vec<u32> = self
.request_ecu(server, ff, 4)?
.iter()
.map(|x| *x as u32)
.collect();
Ok(vec![
ObdValue::new(
"Oxygen sensor 3 Lambda",
ObdUnitType::Raw((r[0] << 8 | r[1]) as f32 * (2.0 / 65536.0)),
),
ObdValue::new(
"Oxygen sensor 3 Current",
ObdUnitType::Raw(((r[2] << 8 | r[3]) as f32 / 256.0) - 128.0),
),
])
}
Standard(OxygenSensor4LambdaCurrent) => {
let r: Vec<u32> = self
.request_ecu(server, ff, 4)?
.iter()
.map(|x| *x as u32)
.collect();
Ok(vec![
ObdValue::new(
"Oxygen sensor 4 Lambda",
ObdUnitType::Raw((r[0] << 8 | r[1]) as f32 * (2.0 / 65536.0)),
),
ObdValue::new(
"Oxygen sensor 4 Current",
ObdUnitType::Raw(((r[2] << 8 | r[3]) as f32 / 256.0) - 128.0),
),
])
}
Standard(OxygenSensor5LambdaCurrent) => {
let r: Vec<u32> = self
.request_ecu(server, ff, 4)?
.iter()
.map(|x| *x as u32)
.collect();
Ok(vec![
ObdValue::new(
"Oxygen sensor 5 Lambda",
ObdUnitType::Raw((r[0] << 8 | r[1]) as f32 * (2.0 / 65536.0)),
),
ObdValue::new(
"Oxygen sensor 5 Current",
ObdUnitType::Raw(((r[2] << 8 | r[3]) as f32 / 256.0) - 128.0),
),
])
}
Standard(OxygenSensor6LambdaCurrent) => {
let r: Vec<u32> = self
.request_ecu(server, ff, 4)?
.iter()
.map(|x| *x as u32)
.collect();
Ok(vec![
ObdValue::new(
"Oxygen sensor 6 Lambda",
ObdUnitType::Raw((r[0] << 8 | r[1]) as f32 * (2.0 / 65536.0)),
),
ObdValue::new(
"Oxygen sensor 6 Current",
ObdUnitType::Raw(((r[2] << 8 | r[3]) as f32 / 256.0) - 128.0),
),
])
}
Standard(OxygenSensor7LambdaCurrent) => {
let r: Vec<u32> = self
.request_ecu(server, ff, 4)?
.iter()
.map(|x| *x as u32)
.collect();
Ok(vec![
ObdValue::new(
"Oxygen sensor 7 Lambda",
ObdUnitType::Raw((r[0] << 8 | r[1]) as f32 * (2.0 / 65536.0)),
),
ObdValue::new(
"Oxygen sensor 7 Current",
ObdUnitType::Raw(((r[2] << 8 | r[3]) as f32 / 256.0) - 128.0),
),
])
}
Standard(OxygenSensor8LambdaCurrent) => {
let r: Vec<u32> = self
.request_ecu(server, ff, 4)?
.iter()
.map(|x| *x as u32)
.collect();
Ok(vec![
ObdValue::new(
"Oxygen sensor 8 Lambda",
ObdUnitType::Raw((r[0] << 8 | r[1]) as f32 * (2.0 / 65536.0)),
),
ObdValue::new(
"Oxygen sensor 8 Current",
ObdUnitType::Raw(((r[2] << 8 | r[3]) as f32 / 256.0) - 128.0),
),
])
}
Standard(CatTempBank1Sensor1) => {
let r: Vec<u32> = self
.request_ecu(server, ff, 2)?
.iter()
.map(|x| *x as u32)
.collect();
Ok(vec![ObdValue::new(
"Catalyst Temperature bank 1, sensor 1",
ObdUnitType::Temperature(Temperature::from_celsius(
((r[0] << 8 | r[1]) as f32 / 10.0) - 40.0,
)),
)])
}
Standard(CatTempBank2Sensor1) => {
let r: Vec<u32> = self
.request_ecu(server, ff, 2)?
.iter()
.map(|x| *x as u32)
.collect();
Ok(vec![ObdValue::new(
"Catalyst Temperature bank 2, sensor 1",
ObdUnitType::Temperature(Temperature::from_celsius(
((r[0] << 8 | r[1]) as f32 / 10.0) - 40.0,
)),
)])
}
Standard(CatTempBank1Sensor2) => {
let r: Vec<u32> = self
.request_ecu(server, ff, 2)?
.iter()
.map(|x| *x as u32)
.collect();
Ok(vec![ObdValue::new(
"Catalyst Temperature bank 1, sensor 2",
ObdUnitType::Temperature(Temperature::from_celsius(
((r[0] << 8 | r[1]) as f32 / 10.0) - 40.0,
)),
)])
}
Standard(CatTempBank2Sensor2) => {
let r: Vec<u32> = self
.request_ecu(server, ff, 2)?
.iter()
.map(|x| *x as u32)
.collect();
Ok(vec![ObdValue::new(
"Catalyst Temperature bank 2, sensor 2",
ObdUnitType::Temperature(Temperature::from_celsius(
((r[0] << 8 | r[1]) as f32 / 10.0) - 40.0,
)),
)])
}
Standard(PidSupport4160) => Ok(vec![ObdValue::new(
"PID support 41-60",
ObdUnitType::ByteArray(self.request_ecu(server, ff, 4)?),
)]),
Standard(MonitorStatusDriveCycle) => Ok(vec![ObdValue::new(
"Monitor status this drive cycle",
ObdUnitType::ByteArray(self.request_ecu(server, ff, 4)?),
)]),
Standard(ControlModuleVoltage) => {
let r: Vec<u32> = self
.request_ecu(server, ff, 2)?
.iter()
.map(|x| *x as u32)
.collect();
Ok(vec![ObdValue::new(
"Control module voltage",
ObdUnitType::Volts((r[0] << 8 | r[1]) as f32 / 1000.0),
)])
}
Standard(AbsLoadValue) => {
let r: Vec<u32> = self
.request_ecu(server, ff, 2)?
.iter()
.map(|x| *x as u32)
.collect();
Ok(vec![ObdValue::new(
"Absolute load value",
ObdUnitType::Percent((r[0] << 8 | r[1]) as f32 * (100.0 / 255.0)),
)])
}
Standard(CommandedLambda) => {
let r: Vec<u32> = self
.request_ecu(server, ff, 2)?
.iter()
.map(|x| *x as u32)
.collect();
Ok(vec![ObdValue::new(
"Commanded Lambda",
ObdUnitType::Raw((r[0] << 8 | r[1]) as f32 * (2.0 / 65536.0)),
)])
}
Standard(RelativeThrottlePosition) => {
self.get_percentage_1_byte(server, ff, "Relative throttle position")
}
Standard(AmbientAirTemp) => Ok(vec![ObdValue::new(
"Ambient air temperature",
ObdUnitType::Temperature(Temperature::from_celsius(
self.request_ecu(server, ff, 1)?[0] as f32 - 40.0,
)),
)]),
Standard(AbsoluteThrottlePositionB) => {
self.get_percentage_1_byte(server, ff, "Absolute throttle position B")
}
Standard(AbsoluteThrottlePositionC) => {
self.get_percentage_1_byte(server, ff, "Absolute throttle position C")
}
Standard(AbsoluteThrottlePositionD) => {
self.get_percentage_1_byte(server, ff, "Absolute throttle position D")
}
Standard(AbsoluteThrottlePositionE) => {
self.get_percentage_1_byte(server, ff, "Absolute throttle position E")
}
Standard(AbsoluteThrottlePositionF) => {
self.get_percentage_1_byte(server, ff, "Absolute throttle position F")
}
Standard(CommandedThrottleActuator) => {
self.get_percentage_1_byte(server, ff, "Commanded throttle actuator")
}
Standard(TimeRunSinceMILOn) => {
let r: Vec<u32> = self
.request_ecu(server, ff, 2)?
.iter()
.map(|x| *x as u32)
.collect();
Ok(vec![ObdValue::new(
"Time run with MIL on",
ObdUnitType::Time(Time::from_seconds((r[0] << 8 | r[1]) as f32 * 60.0)),
)])
}
Standard(TimeSinceCodesCleared) => {
let r: Vec<u32> = self
.request_ecu(server, ff, 2)?
.iter()
.map(|x| *x as u32)
.collect();
Ok(vec![ObdValue::new(
"Time since trouble codes cleared",
ObdUnitType::Time(Time::from_seconds((r[0] << 8 | r[1]) as f32 * 60.0)),
)])
}
Standard(MaximumLambdaVoltageCurrentPressure) => {
let r: Vec<u32> = self
.request_ecu(server, ff, 4)?
.iter()
.map(|x| *x as u32)
.collect();
Ok(vec![
ObdValue::new("Maximum value for Lambda", ObdUnitType::Raw(r[0] as f32)),
ObdValue::new(
"Maximum value for oxygen sensor voltage",
ObdUnitType::Volts(r[1] as f32),
),
ObdValue::new(
"Maximum value oxygen sensor current",
ObdUnitType::Raw(r[2] as f32),
),
ObdValue::new(
"Maximum value for intake manifold absolute pressure",
ObdUnitType::Pressure(Pressure::from_kilo_pascal(r[3] as f32 * 10.0)),
),
])
}
Standard(MaximumAirFlowRate) => {
let r: Vec<u32> = self
.request_ecu(server, ff, 1)?
.iter()
.map(|x| *x as u32)
.collect();
Ok(vec![ObdValue::new(
"Maximum value for air flow rate from mass air flow sensor",
ObdUnitType::Raw(r[0] as f32 * 10.0),
)])
}
Standard(FuelType) => Ok(vec![ObdValue::new(
"Fuel type",
ObdUnitType::Encoded(ObdEnumValue::FuelType(FuelTypeCodingByte::from(
self.request_ecu(server, ff, 1)?[0],
))),
)]),
Standard(EthanolFuelPercentage) => {
self.get_percentage_1_byte(server, ff, "Ethanol fuel")
}
Standard(AbsoluteEvapSystemVaporPressure) => {
let r: Vec<i32> = self
.request_ecu(server, ff, 2)?
.iter()
.map(|x| *x as i32)
.collect();
Ok(vec![ObdValue::new(
"Absolute evaporative system vapor pressure",
ObdUnitType::Pressure(Pressure::from_kilo_pascal(
(r[0] << 8 | r[1]) as f32 / 200.0,
)),
)])
}
Standard(EvapSystemVaporPressure2) => {
let r: Vec<i32> = self
.request_ecu(server, ff, 2)?
.iter()
.map(|x| *x as i32)
.collect();
Ok(vec![ObdValue::new(
"Evaporative system vapor pressure",
ObdUnitType::Pressure(Pressure::from_kilo_pascal(
(r[0] << 8 | r[1]) as f32 / 1000.0,
)),
)])
}
Standard(ShortTermSecondaryOxygenSensorTrimBank1and3) => {
let r: Vec<u32> = self
.request_ecu(server, ff, 2)?
.iter()
.map(|x| *x as u32)
.collect();
Ok(vec![
ObdValue::new(
"Short term secondary oxygen sensor trim bank 1",
ObdUnitType::Percent(r[0] as f32 * (100.0 / 128.0) - 100.0),
),
ObdValue::new(
"Short term secondary oxygen sensor trim bank 3",
ObdUnitType::Percent(r[1] as f32 * (100.0 / 128.0) - 100.0),
),
])
}
Standard(LongTermSecondaryOxygenSensorTrimBank1and3) => {
let r: Vec<u32> = self
.request_ecu(server, ff, 2)?
.iter()
.map(|x| *x as u32)
.collect();
Ok(vec![
ObdValue::new(
"Long term secondary oxygen sensor trim bank 1",
ObdUnitType::Percent(r[0] as f32 * (100.0 / 128.0) - 100.0),
),
ObdValue::new(
"Long term secondary oxygen sensor trim bank 3",
ObdUnitType::Percent(r[1] as f32 * (100.0 / 128.0) - 100.0),
),
])
}
Standard(ShortTermSecondaryOxygenSensorTrimBank2and4) => {
let r: Vec<u32> = self
.request_ecu(server, ff, 2)?
.iter()
.map(|x| *x as u32)
.collect();
Ok(vec![
ObdValue::new(
"Short term secondary oxygen sensor trim bank 2",
ObdUnitType::Percent(r[0] as f32 * (100.0 / 128.0) - 100.0),
),
ObdValue::new(
"Short term secondary oxygen sensor trim bank 4",
ObdUnitType::Percent(r[1] as f32 * (100.0 / 128.0) - 100.0),
),
])
}
Standard(LongTermSecondaryOxygenSensorTrimBank2and4) => {
let r: Vec<u32> = self
.request_ecu(server, ff, 2)?
.iter()
.map(|x| *x as u32)
.collect();
Ok(vec![
ObdValue::new(
"Long term secondary oxygen sensor trim bank 2",
ObdUnitType::Percent(r[0] as f32 * (100.0 / 128.0) - 100.0),
),
ObdValue::new(
"Long term secondary oxygen sensor trim bank 4",
ObdUnitType::Percent(r[1] as f32 * (100.0 / 128.0) - 100.0),
),
])
}
Standard(FuelRailAbsPressure) => {
let r: Vec<u32> = self
.request_ecu(server, ff, 2)?
.iter()
.map(|x| *x as u32)
.collect();
Ok(vec![ObdValue::new(
"Fuel rail absolute pressure",
ObdUnitType::Pressure(Pressure::from_kilo_pascal(
(r[0] << 8 | r[1]) as f32 * 10.0,
)),
)])
}
Standard(RelativePedalPosition) => {
self.get_percentage_1_byte(server, ff, "Relative accelerator pedal position")
}
Standard(HybridBatteryPackLife) => {
self.get_percentage_1_byte(server, ff, "Hybrid battery pack remaining life")
}
Standard(EmissionsStandard) => Ok(vec![ObdValue::new(
"Emission requirments to which the vehicle is designed",
ObdUnitType::ByteArray(self.request_ecu(server, ff, 1)?),
)]),
Standard(PidSupport6180) => Ok(vec![ObdValue::new(
"PID support 61-80",
ObdUnitType::ByteArray(self.request_ecu(server, ff, 4)?),
)]),
_ => Err(DiagError::NotImplemented(format!(
"Parsing {:02X?}",
self.0
))),
}
}
}