Skip to content

Commit

Permalink
Add electrical current and voltage modules
Browse files Browse the repository at this point in the history
  • Loading branch information
yorickdewid committed Mar 11, 2024
1 parent fbf87c2 commit 9c3d2be
Show file tree
Hide file tree
Showing 2 changed files with 161 additions and 1 deletion.
67 changes: 66 additions & 1 deletion src/slots.rs
Expand Up @@ -88,7 +88,7 @@ pub mod rotational_velocity {
return None;
}

Some(RESOLUTION.dec(i16::from_le_bytes(value) as f32) as u16)
Some(RESOLUTION.dec(u16::from_le_bytes(value) as f32) as u16)
}

pub fn enc(value: Option<u16>) -> [u8; 2] {
Expand Down Expand Up @@ -142,6 +142,71 @@ pub mod temperature2 {
}
}

pub mod electrical_current {
const RESOLUTION: super::Param = super::Param {
scale: 1.0,
offset: -125.0,
limit_lower: -125.0,
limit_upper: 125.0,
};

pub fn dec(value: u8) -> Option<i8> {
if value == crate::PDU_NOT_AVAILABLE {
return None;
}

Some(RESOLUTION.dec(value as f32) as i8)
}

pub fn enc(value: Option<i8>) -> u8 {
value.map_or(crate::PDU_NOT_AVAILABLE, |v| RESOLUTION.enc(v as f32) as u8)
}
}

pub mod electrical_current2 {
const RESOLUTION: super::Param = super::Param {
scale: 1.0,
offset: 0.0,
limit_lower: 0.0,
limit_upper: 250.0,
};

pub fn dec(value: u8) -> Option<u8> {
if value == crate::PDU_NOT_AVAILABLE {
return None;
}

Some(RESOLUTION.dec(value as f32) as u8)
}

pub fn enc(value: Option<u8>) -> u8 {
value.map_or(crate::PDU_NOT_AVAILABLE, |v| RESOLUTION.enc(v as f32) as u8)
}
}

pub mod electrical_voltage {
const RESOLUTION: super::Param = super::Param {
scale: 0.05,
offset: 0.0,
limit_lower: 0.0,
limit_upper: 3212.75,
};

pub fn dec(value: [u8; 2]) -> Option<u16> {
if value == [crate::PDU_NOT_AVAILABLE; 2] {
return None;
}

Some(RESOLUTION.dec(u16::from_le_bytes(value) as f32) as u16)
}

pub fn enc(value: Option<u16>) -> [u8; 2] {
value.map_or([crate::PDU_NOT_AVAILABLE; 2], |v| {
(RESOLUTION.enc(v as f32) as u16).to_le_bytes()
})
}
}

pub mod position_level {
const RESOLUTION: super::Param = super::Param {
scale: 0.4,
Expand Down
95 changes: 95 additions & 0 deletions src/spn.rs
Expand Up @@ -1604,6 +1604,72 @@ impl core::fmt::Display for TankInformation1Message {
}
}

//Bit Start Position /Bytes Length SPN Description SPN
//
//1 1 byte Net Battery Current 114
//2 1 byte Alternator Current 115
//3-4 2 bytes Alternator Potential (Voltage) 167
//5-6 2 bytes Electrical Potential (Voltage) 168
//7-8 2 bytes Battery Potential (Voltage), Switched 158

//
// Vehicle Electrical Power
//

pub struct VehicleElectricalPowerMessage {
/// Net flow of electrical current into/out of the battery or batteries.
pub net_battery_current: Option<i8>,
/// Measure of electrical current flow from the alternator. Alternator Current (High
/// Range/Resolution) parameter SPN 1795 has a higher range and resolution of the same parameter.
pub alternator_current: Option<u8>,
/// Electrical potential measured at the alternator output.
pub alternator_potential: Option<u16>,
/// Measured electrical potential of the battery.
pub electrical_potential: Option<u16>,
/// Electrical potential measured at the input of the electronic control
/// unit supplied through a switching device.
pub battery_potential: Option<u16>,
}

impl VehicleElectricalPowerMessage {
pub fn from_pdu(pdu: &[u8]) -> Self {
Self {
net_battery_current: slots::electrical_current::dec(pdu[0]),
alternator_current: slots::electrical_current2::dec(pdu[1]),
alternator_potential: slots::electrical_voltage::dec([pdu[2], pdu[3]]),
electrical_potential: slots::electrical_voltage::dec([pdu[4], pdu[5]]),
battery_potential: slots::electrical_voltage::dec([pdu[6], pdu[7]]),
}
}

pub fn to_pdu(&self) -> [u8; 8] {
[
slots::electrical_current::enc(self.net_battery_current),
slots::electrical_current2::enc(self.alternator_current),
slots::electrical_voltage::enc(self.alternator_potential)[0],
slots::electrical_voltage::enc(self.alternator_potential)[1],
slots::electrical_voltage::enc(self.electrical_potential)[0],
slots::electrical_voltage::enc(self.electrical_potential)[1],
slots::electrical_voltage::enc(self.battery_potential)[0],
slots::electrical_voltage::enc(self.battery_potential)[1],
]
}
}

impl core::fmt::Display for VehicleElectricalPowerMessage {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(
f,
"Net battery current: {} A; Alternator current: {} A; Alternator potential: {} V; Electrical potential: {} V; Battery potential: {} V",
self.net_battery_current.unwrap_or(0),
self.alternator_current.unwrap_or(0),
self.alternator_potential.unwrap_or(0),
self.electrical_potential.unwrap_or(0),
self.battery_potential.unwrap_or(0)
)
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down Expand Up @@ -1864,4 +1930,33 @@ mod tests {
None
);
}

#[test]
fn vehicle_electrical_power_message() {
let electrical_power_message_encoded = VehicleElectricalPowerMessage {
net_battery_current: Some(-16),
alternator_current: Some(5),
alternator_potential: Some(235),
electrical_potential: Some(1731),
battery_potential: Some(947),
}
.to_pdu();
let electrical_power_message_decoded =
VehicleElectricalPowerMessage::from_pdu(&electrical_power_message_encoded);

assert_eq!(
electrical_power_message_decoded.net_battery_current,
Some(-16)
);
assert_eq!(electrical_power_message_decoded.alternator_current, Some(5));
assert_eq!(
electrical_power_message_decoded.alternator_potential,
Some(235)
);
assert_eq!(
electrical_power_message_decoded.electrical_potential,
Some(1731)
);
assert_eq!(electrical_power_message_decoded.battery_potential, Some(947));
}
}

0 comments on commit 9c3d2be

Please sign in to comment.