use std::collections::HashMap;
use serde::{Deserialize, Serialize, Serializer};
#[derive(Debug, Deserialize)]
pub enum MultiType {
Float(f64),
Int(i64),
Str(String),
Vec(Vec<MultiType>),
Map(HashMap<String, MultiType>),
}
pub struct ParseResult {
pub length: usize,
pub data: HashMap<String, MultiType>,
}
impl Serialize for MultiType {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match self {
MultiType::Float(f) => serializer.serialize_f64(*f),
MultiType::Int(i) => serializer.serialize_i64(*i),
MultiType::Str(s) => serializer.serialize_str(s),
MultiType::Vec(v) => v.serialize(serializer),
MultiType::Map(m) => m.serialize(serializer),
}
}
}
pub struct Gbt32950Decoder {
pub data_type: HashMap<&'static str, &'static str>,
pub data_type_ack: HashMap<&'static str, &'static str>,
pub encrypt_type: HashMap<&'static str, &'static str>,
pub car_status: HashMap<&'static str, &'static str>,
pub charge_status: HashMap<&'static str, &'static str>,
pub run_mode: HashMap<&'static str, &'static str>,
pub dcdc_status: HashMap<&'static str, &'static str>,
pub motor_status: HashMap<&'static str, &'static str>,
pub engine_status: HashMap<&'static str, &'static str>,
pub alarm_level: HashMap<&'static str, &'static str>,
pub ota_type: HashMap<&'static str, &'static str>,
pub ota_status: HashMap<&'static str, &'static str>,
pub ota_result: HashMap<&'static str, &'static str>,
}
impl Gbt32950Decoder {
pub fn new() -> Self {
let mut data_type = HashMap::new();
data_type.insert("01", "车辆登录");
data_type.insert("02", "实时信息上报");
data_type.insert("03", "补发信息上报");
data_type.insert("04", "车辆登出");
data_type.insert("07", "心跳");
data_type.insert("08", "终端校时");
data_type.insert("80", "查询命令");
data_type.insert("81", "设置命令");
data_type.insert("82", "车载终端控制命令");
data_type.insert("C1", "升级结果状态上报");
data_type.insert("C2", "ECU升级结果");
data_type.insert("C3", "短信唤醒登出");
data_type.insert("C4", "DTC数据上报");
data_type.insert("C5", "T-BOX注册");
data_type.insert("C6", "唯一识别码");
data_type.insert("C7", "ECU信息查询");
data_type.insert("C8", "唤醒方式");
data_type.insert("C9", "自定义报警");
data_type.insert("CA", "升级进度上报");
data_type.insert("CD", "通用报警");
let mut data_type_ack = HashMap::new();
data_type_ack.insert("01", "成功");
data_type_ack.insert("02", "错误");
data_type_ack.insert("03", "VIN重复");
data_type_ack.insert("04", "未登录");
data_type_ack.insert("FE", "命令包");
data_type_ack.insert("0A", "供应商为空或者供应商编码不存在");
data_type_ack.insert("0B", "T-box 类型为空或者 T-box 类型不存在");
data_type_ack.insert("0C", "T-box 编号为空或格式错误");
data_type_ack.insert("0D", "ICCID 为空或格式错误");
data_type_ack.insert("0E", "IMEI为空或格式错误");
data_type_ack.insert("0F", "T-box 已注册使用");
data_type_ack.insert("10", "tuid 编号为空或格式错误");
let mut encrypt_type = HashMap::new();
encrypt_type.insert("01", "不加密");
encrypt_type.insert("02", "RSA加密");
encrypt_type.insert("03", "AES128加密");
encrypt_type.insert("FE", "异常");
encrypt_type.insert("FF", "无效");
let mut car_status = HashMap::new();
car_status.insert("01", "车辆启动状态");
car_status.insert("02", "熄火");
car_status.insert("03", "其他");
car_status.insert("FE", "异常");
car_status.insert("FF", "无效");
let mut charge_status = HashMap::new();
charge_status.insert("01", "停车充电");
charge_status.insert("02", "行驶充电");
charge_status.insert("03", "未充电");
charge_status.insert("04", "充电完成");
charge_status.insert("FE", "异常");
charge_status.insert("FF", "无效");
let mut run_mode = HashMap::new();
run_mode.insert("01", "纯电");
run_mode.insert("02", "混动");
run_mode.insert("03", "燃油");
run_mode.insert("FE", "异常");
run_mode.insert("FF", "无效");
let mut dcdc_status = HashMap::new();
dcdc_status.insert("01", "工作");
dcdc_status.insert("02", "断开");
dcdc_status.insert("FE", "异常");
dcdc_status.insert("FF", "无效");
let mut motor_status = HashMap::new();
motor_status.insert("01", "耗电");
motor_status.insert("02", "发电");
motor_status.insert("03", "关闭");
motor_status.insert("04", "准备");
motor_status.insert("FE", "异常");
motor_status.insert("FF", "无效");
let mut engine_status = HashMap::new();
engine_status.insert("01", "启动");
engine_status.insert("02", "关闭");
engine_status.insert("FE", "异常");
engine_status.insert("FF", "无效");
let mut alarm_level = HashMap::new();
alarm_level.insert("00", "无故障");
alarm_level.insert("01", "一级");
alarm_level.insert("02", "二级");
alarm_level.insert("03", "三级");
alarm_level.insert("FE", "异常");
alarm_level.insert("FF", "无效");
let mut ota_type = HashMap::new();
ota_type.insert("01", "启动升级");
ota_type.insert("02", "升级结果");
let mut ota_status = HashMap::new();
ota_status.insert("00", "成功");
ota_status.insert("01", "失败");
let mut ota_result = HashMap::new();
ota_result.insert("00", "成功");
ota_result.insert("01", "失败");
Self {
data_type,
data_type_ack,
encrypt_type,
car_status,
charge_status,
run_mode,
dcdc_status,
motor_status,
engine_status,
alarm_level,
ota_type,
ota_status,
ota_result,
}
}
fn get_val_byte(&self, hex: &str, scale: f64, offset: i32) -> String {
if hex == "FE" {
return "异常".to_string();
}
if hex == "FF" {
return "无效".to_string();
}
let value = self.hex2int(hex) as f64 * scale + offset as f64;
value.to_string()
}
fn get_val_word(&self, hex_high: &str, hex_low: &str, scale: f64, offset: i32) -> String {
let hex_str = format!("{}{}", hex_high, hex_low);
if hex_str == "FFFE" {
return "异常".to_string();
}
if hex_str == "FFFF" {
return "无效".to_string();
}
let value = self.hex2int(&hex_str) as f64 * scale + offset as f64;
value.to_string()
}
fn get_float_word(
&self,
hex_high: &str,
hex_low: &str,
scale: f64,
offset: i32,
precision: i32,
) -> String {
let hex_str = format!("{}{}", hex_high, hex_low);
if hex_str == "FFFE" {
return "异常".to_string();
}
if hex_str == "FFFF" {
return "无效".to_string();
}
let value = self.hex2int(&hex_str) as f64 * scale + offset as f64;
format!("{:.1$}", value, precision as usize)
}
fn get_float_dword(&self, hex_str: &str, scale: f64, offset: i32, precision: i32) -> String {
let invalid_str = "FFFFFFFF";
if hex_str == "FFFFFFFE" {
return "异常".to_string();
}
if hex_str == invalid_str {
return "无效".to_string();
}
let value = self.hex2long(hex_str) as f64 * scale + offset as f64;
format!("{:.1$}", value, precision as usize)
}
fn get_general_alarm_dec(&self, bit: u32, alarm_flag: u64) -> String {
if (alarm_flag & (1 << bit)) != 0 {
"报警".to_string()
} else {
"正常".to_string()
}
}
fn hex2int(&self, hex: &str) -> i32 {
i32::from_str_radix(hex, 16).unwrap_or(0)
}
fn hex2long(&self, hex: &str) -> i64 {
i64::from_str_radix(hex, 16).unwrap_or(0)
}
fn hex2integer_e(&self, hex: String) -> i32 {
hex.parse::<i32>().unwrap_or(0)
}
pub fn get_time(&self, y: &str, m: &str, d: &str, h: &str, min: &str, s: &str) -> String {
format!(
"{:02}-{:02}-{:02} {:02}:{:02}:{:02}",
self.hex2int(y),
self.hex2int(m),
self.hex2int(d),
self.hex2int(h),
self.hex2int(min),
self.hex2int(s)
)
}
pub fn format_hex(&self, s: &str) -> String {
let s = s.replace(" ", "").to_uppercase();
let mut out = String::new();
let chars: Vec<char> = s.chars().collect();
for (i, c) in chars.iter().enumerate() {
out.push(*c);
if i % 2 == 1 && i != chars.len() - 1 {
out.push(' ');
}
}
out
}
pub fn parse_login(&self, data: &[&str]) -> HashMap<String, MultiType> {
let mut map = HashMap::new();
if data.len() < 30 {
return map;
}
map.insert(
"数据采集时间".to_string(),
MultiType::Str(self.get_time(data[0], data[1], data[2], data[3], data[4], data[5])),
);
let login_sn = format!("{}{}", data[6], data[7]);
map.insert(
"登录流水号".to_string(),
MultiType::Int(self.hex2int(&login_sn) as i64),
);
let iccid: String = data[8..28]
.iter()
.map(|x| char::from(self.hex2int(x) as u8))
.collect();
map.insert("ICCID".to_string(), MultiType::Str(iccid));
let sys_count = self.hex2int(data[28]);
let sys_len = self.hex2int(data[29]);
map.insert(
"可充电储能系统数".to_string(),
MultiType::Int(sys_count as i64),
);
map.insert(
"可充电储能系统编码长度".to_string(),
MultiType::Int(sys_len as i64),
);
let mut sys_code = String::new();
for i in 0..(sys_count * sys_len) as usize {
if 30 + i < data.len() {
sys_code.push(char::from(self.hex2int(data[30 + i]) as u8));
}
}
map.insert("可充电储能系统编码".to_string(), MultiType::Str(sys_code));
if data.len() > 30 + (sys_count * sys_len) as usize {
let charge_time_high = self.hex2int(data[30 + (sys_count * sys_len) as usize]);
let charge_time_low = self.hex2int(data[31 + (sys_count * sys_len) as usize]);
let charge_time = format!("{}.{:02}", charge_time_high, charge_time_low);
map.insert("充电时间(h)".to_string(), MultiType::Str(charge_time));
}
if data.len() > 32 + (sys_count * sys_len) as usize {
let mileage_high = self.hex2int(data[32 + (sys_count * sys_len) as usize]);
let mileage_low = self.hex2int(data[33 + (sys_count * sys_len) as usize]);
let mileage = format!("{}.{:02}", mileage_high, mileage_low);
map.insert("累计充电次数".to_string(), MultiType::Str(mileage));
}
map
}
pub fn parse_logout(&self, data: &[&str]) -> HashMap<String, MultiType> {
let mut map = HashMap::new();
if data.len() < 8 {
return map;
}
map.insert(
"登出时间".to_string(),
MultiType::Str(self.get_time(data[0], data[1], data[2], data[3], data[4], data[5])),
);
let logout_sn = format!("{}{}", data[6], data[7]);
map.insert(
"登出流水号".to_string(),
MultiType::Int(self.hex2int(&logout_sn) as i64),
);
map
}
pub fn parse_vehicle(&self, data: &[&str], start_char: &str) -> ParseResult {
let mut map = HashMap::new();
let mut length = 0;
let mut max = 20;
if "$$" == start_char {
max = 18;
}
if data.len() > max {
length = max;
}
if data.len() > 1 {
let car_status = self.car_status.get(data[1]).unwrap_or(&"未知");
map.insert(
"车辆状态".to_string(),
MultiType::Str(car_status.to_string()),
);
}
if data.len() > 2 {
let charge_status = self.charge_status.get(data[2]).unwrap_or(&"未知");
map.insert(
"充电状态".to_string(),
MultiType::Str(charge_status.to_string()),
);
}
if data.len() > 3 {
let run_mode = self.run_mode.get(data[3]).unwrap_or(&"未知");
map.insert("运行模式".to_string(), MultiType::Str(run_mode.to_string()));
}
if data.len() > 5 {
let speed = self.get_float_word(data[4], data[5], 0.1, 0, 1);
map.insert("车速".to_string(), MultiType::Str(speed));
}
if data.len() > 9 {
let mileage_hex = format!("{}{}{}{}", data[6], data[7], data[8], data[9]);
let mileage = self.get_float_dword(&mileage_hex, 0.1, 0, 1);
map.insert("累计里程".to_string(), MultiType::Str(mileage));
}
if data.len() > 11 {
let voltage = self.get_float_word(data[10], data[11], 0.1, 0, 1);
map.insert("总电压".to_string(), MultiType::Str(voltage));
}
if data.len() > 13 {
let current = self.get_float_word(data[12], data[13], 0.1, -1000, 1);
map.insert("总电流".to_string(), MultiType::Str(current));
}
if data.len() > 14 {
let soc = self.get_val_byte(data[14], 1.0, 0);
map.insert("SOC".to_string(), MultiType::Str(soc));
}
if data.len() > 15 {
let dcdc_status = self.dcdc_status.get(data[15]).unwrap_or(&"未知");
map.insert(
"DCDC状态".to_string(),
MultiType::Str(dcdc_status.to_string()),
);
}
if data.len() > 16 {
let gear = self.hex2int(data[16]);
let brake = if (gear & 0x10) != 0 { "有" } else { "无" };
let drive = if (gear & 0x20) != 0 { "有" } else { "无" };
let gear_num = gear & 0x0F;
let gear_str = match gear_num {
0 => "空档",
1..=12 => &format!("{}档", gear_num),
13 => "倒挡",
14 => "自动D档",
15 => "停车P档",
_ => "未知",
};
map.insert("制动".to_string(), MultiType::Str(brake.to_string()));
map.insert("驱动".to_string(), MultiType::Str(drive.to_string()));
map.insert("档位".to_string(), MultiType::Str(gear_str.to_string()));
}
if data.len() > 18 {
let resistance = self.hex2int(&(format!("{}{}", data[17], data[18])));
map.insert(
"绝缘电阻".to_string(),
MultiType::Str(resistance.to_string()),
);
}
if start_char == "##" && data.len() > 20 {
let accel_pedal = match data[19] {
"FE" => "异常",
"FF" => "无效",
_ => &format!("{}%", self.hex2int(data[19])),
};
map.insert(
"加速踏板行程值".to_string(),
MultiType::Str(accel_pedal.to_string()),
);
let brake_pedal = match data[20] {
"65" => "有效",
"FF" => "无效",
_ => &format!("{}%", self.hex2int(data[20])),
};
map.insert(
"制动踏板状态".to_string(),
MultiType::Str(brake_pedal.to_string()),
);
}
ParseResult {
length: length,
data: map,
}
}
pub fn parse_motors(&self, data: &[&str], start_char: &str) -> ParseResult {
let mut map = HashMap::new();
let count = self.hex2int(data[1]) as usize;
let mut len = 0;
let mut max = 12;
if "$$" == start_char {
max = 10;
}
if data.len() > count * max + 1 {
len = count * max + 1;
}
map.insert("驱动电机个数".to_string(), MultiType::Int(count as i64));
let mut motors = Vec::new();
for i in 0..count {
let base = (i * if start_char == "$$" { 10 } else { 12 }) + 2;
if base + (if start_char == "$$" { 9 } else { 11 }) >= data.len() {
break;
}
let mut motor = HashMap::new();
let motor_idx = self.hex2int(data[base]);
motor.insert("驱动电机序号".to_string(), MultiType::Int(motor_idx as i64));
if base + 1 < data.len() {
let motor_status = self
.motor_status
.get(data[base + 1])
.unwrap_or(&data[base + 1]);
motor.insert(
"驱动电机状态".to_string(),
MultiType::Str(motor_status.to_string()),
);
}
if base + 2 < data.len() {
let controller_temp = self.hex2int(data[base + 2]) - 0x28;
motor.insert(
"驱动电机控制器温度".to_string(),
MultiType::Int(controller_temp as i64),
);
}
if base + 4 < data.len() {
let speed_hex = format!("{}{}", data[base + 3], data[base + 4]);
let speed = self.hex2int(&speed_hex) - 0x4e20;
motor.insert("驱动电机转速".to_string(), MultiType::Int(speed as i64));
}
if start_char == "##" {
if base + 6 < data.len() {
let torque = self.get_val_word(data[base + 5], data[base + 6], 0.1, -2000);
if torque == "FFFE" || torque == "FFFF" {
motor.insert("驱动电机转矩".to_string(), MultiType::Str(torque));
} else {
motor.insert(
"驱动电机转矩".to_string(),
MultiType::Float(torque.parse::<f64>().unwrap_or(0.0)),
);
}
}
if base + 7 < data.len() {
let motor_temp = self.hex2int(data[base + 7]) - 0x28;
motor.insert(
"驱动电机温度".to_string(),
MultiType::Int(motor_temp as i64),
);
}
if base + 9 < data.len() {
let voltage = self.get_float_word(data[base + 8], data[base + 9], 0.1, 0, 1);
motor.insert(
"电机控制器输入电压".to_string(),
MultiType::Float(voltage.parse::<f64>().unwrap_or(0.0)),
);
}
if base + 11 < data.len() {
let current =
self.get_float_word(data[base + 10], data[base + 11], 0.1, -1000, 1);
motor.insert(
"电机控制器直流母线电流".to_string(),
MultiType::Float(current.parse::<f64>().unwrap_or(0.0)),
);
}
} else if start_char == "$$" {
if base + 8 < data.len() {
let torque_hex = format!(
"{}{}{}{}",
data[base + 5],
data[base + 6],
data[base + 7],
data[base + 8]
);
match torque_hex.as_str() {
"FFFFFE" => motor.insert(
"驱动电机转矩".to_string(),
MultiType::Str("异常".to_string()),
),
"FFFFFF" => motor.insert(
"驱动电机转矩".to_string(),
MultiType::Str("无效".to_string()),
),
_ => {
let value = self.hex2long(&torque_hex) as f64 * 0.1 - 2000.0;
motor.insert("驱动电机转矩".to_string(), MultiType::Float(value))
}
};
}
if base + 9 < data.len() {
let motor_temp = self.hex2int(data[base + 9]) - 0x28;
motor.insert(
"驱动电机温度".to_string(),
MultiType::Int(motor_temp as i64),
);
}
}
motors.push(MultiType::Map(motor));
}
map.insert("驱动电机总成信息".to_string(), MultiType::Vec(motors));
ParseResult {
length: len,
data: map,
}
}
pub fn parse_fuelcell(&self, data: &[&str]) -> ParseResult {
let mut map = HashMap::new();
let voltage = self.get_val_word(data[0], data[1], 0.1, 0);
map.insert("燃料电池电压".to_string(), MultiType::Str(voltage));
let current = self.get_val_word(data[2], data[3], 0.1, 0);
map.insert("燃料电池电流".to_string(), MultiType::Str(current));
let fuel_consumption = self.get_float_word(data[4], data[5], 0.01, 0, 1);
map.insert("燃料消耗率".to_string(), MultiType::Str(fuel_consumption));
let temp_probe_count = self.get_val_word(data[6], data[7], 1.0, 0);
map.insert(
"燃料电池温度探针总数".to_string(),
MultiType::Str(temp_probe_count.clone()),
);
let temp_probe_count_int = self.hex2integer_e(temp_probe_count.clone());
let mut temp_probe_values = Vec::new();
for i in 0..temp_probe_count_int {
if (8 + i as usize) < data.len() {
let temp = self.get_val_byte(data[8 + i as usize], 1.0, 0);
temp_probe_values.push(MultiType::Str(temp));
}
}
map.insert(
"燃料电池温度探针值".to_string(),
MultiType::Vec(temp_probe_values),
);
let mut offset = 8 + temp_probe_count_int as usize;
if offset + 4 < data.len() {
let hydrogen_temp = self.get_val_word(data[offset], data[offset + 1], 0.1, -40);
map.insert(
"氢系统中最高温度".to_string(),
MultiType::Str(hydrogen_temp),
);
let probe_idx = self.get_val_byte(data[offset + 2], 1.0, 0);
map.insert(
"氢系统中最高温度探针代号".to_string(),
MultiType::Str(probe_idx),
);
let hydrogen_conc = self.get_val_word(data[offset + 3], data[offset + 4], 0.01, 0);
map.insert("氢气最高浓度".to_string(), MultiType::Str(hydrogen_conc));
}
offset += 5;
if offset + 2 < data.len() {
let sensor_idx = self.get_val_byte(data[offset], 1.0, 0);
map.insert(
"氢气最高浓度传感器代号".to_string(),
MultiType::Str(sensor_idx),
);
let hydrogen_press = self.get_val_word(data[offset + 1], data[offset + 2], 0.1, 0);
map.insert("氢气最高压力".to_string(), MultiType::Str(hydrogen_press));
}
offset += 3;
if offset + 1 < data.len() {
let press_sensor_idx = self.get_val_byte(data[offset], 1.0, 0);
map.insert(
"氢气最高压力传感器代号".to_string(),
MultiType::Str(press_sensor_idx),
);
let dcdc_status = match data[offset + 1] {
"01" => "工作",
"02" => "断开",
"FE" => "异常",
"FF" => "无效",
_ => "未知",
};
map.insert(
"高压DCDC状态".to_string(),
MultiType::Str(dcdc_status.to_string()),
);
}
ParseResult {
length: offset + 1,
data: map,
}
}
pub fn parse_engine(&self, data: &[&str]) -> ParseResult {
let mut map = HashMap::new();
let engine_status = self.engine_status.get(data[1]).unwrap_or(&data[1]);
map.insert(
"发动机状态".to_string(),
MultiType::Str(engine_status.to_string()),
);
let speed = self.get_val_word(data[2], data[3], 1.0, 0);
map.insert("曲轴转速".to_string(), MultiType::Str(speed));
let fuel_consumption = self.get_float_word(data[4], data[5], 0.01, 0, 1);
map.insert("燃料消耗率".to_string(), MultiType::Str(fuel_consumption));
ParseResult {
length: 5,
data: map,
}
}
pub fn parse_position(&self, data: &[&str], start_char: &str) -> ParseResult {
let mut map = HashMap::new();
if start_char == "##" {
let valid = self.hex2int(data[1]);
map.insert(
"定位有效性".to_string(),
MultiType::Str(if (valid & 0x1) == 1 {
"无效".to_string()
} else {
"有效".to_string()
}),
);
map.insert(
"南北纬".to_string(),
MultiType::Str(if (valid & 0x2) == 0x2 {
"南纬".to_string()
} else {
"北纬".to_string()
}),
);
map.insert(
"东西经".to_string(),
MultiType::Str(if (valid & 0x4) == 0x4 {
"西经".to_string()
} else {
"东经".to_string()
}),
);
let lon_hex = format!("{}{}{}{}", data[2], data[3], data[4], data[5]);
let lon = self.get_float_dword(&lon_hex, 0.000001, 0, 1);
map.insert("经度".to_string(), MultiType::Str(lon));
let lat_hex = format!("{}{}{}{}", data[6], data[7], data[8], data[9]);
let lat = self.get_float_dword(&lat_hex, 0.000001, 0, 1);
map.insert("纬度".to_string(), MultiType::Str(lat));
ParseResult {
length: 9,
data: map,
}
} else
{
let valid = self.hex2int(data[1]);
map.insert(
"定位状态".to_string(),
MultiType::Str(if (valid & 0x1) == 1 {
"无效".to_string()
} else {
"有效".to_string()
}),
);
let coord_system = self.hex2int(data[2]);
let coord_system_str = match coord_system {
1 => "WGS84坐标系",
2 => "GCJ02坐标系",
3 => "其他坐标系",
_ => "未知坐标系",
};
map.insert(
"坐标系".to_string(),
MultiType::Str(coord_system_str.to_string()),
);
let lon_hex = format!("{}{}{}{}", data[3], data[4], data[5], data[6]);
let lon = self.get_float_dword(&lon_hex, 0.000001, 0,1);
map.insert("经度".to_string(), MultiType::Str(lon));
let lat_hex = format!("{}{}{}{}", data[7], data[8], data[9], data[10]);
let lat = self.get_float_dword(&lat_hex, 0.000001, 0,1);
map.insert("纬度".to_string(), MultiType::Str(lat));
ParseResult {
length: 10,
data: map,
}
}
}
pub fn parse_dtc(&self, data: &[&str]) -> HashMap<String, MultiType> {
let mut map = HashMap::new();
if data.len() < 7 {
return map;
}
map.insert(
"数据采集时间".to_string(),
MultiType::Str(self.get_time(data[0], data[1], data[2], data[3], data[4], data[5])),
);
let ecu_count = self.get_val_byte(data[6], 1.0, 0);
map.insert("ECU数目".to_string(), MultiType::Str(ecu_count.clone()));
let ecu_count_int = self.hex2integer_e(ecu_count);
let mut ecu_list = Vec::new();
let mut idx = 7;
for _ in 0..ecu_count_int {
if idx + 3 > data.len() as i32 {
break;
}
let mut ecu = HashMap::new();
ecu.insert(
"ECU编码".to_string(),
MultiType::Str(self.get_val_byte(data[idx as usize], 1.0, 0)),
);
let dtc_count =
self.get_val_word(data[(idx + 1) as usize], data[(idx + 2) as usize], 1.0, 0);
ecu.insert("DTC数目".to_string(), MultiType::Str(dtc_count.clone()));
let dtc_count_int = self.hex2integer_e(dtc_count);
let mut dtcs = Vec::new();
idx += 3;
for _ in 0..dtc_count_int {
if idx + 3 >= data.len() as i32 {
break;
}
let dtc = format!(
"{}{}{}{}",
data[idx as usize],
data[(idx + 1) as usize],
data[(idx + 2) as usize],
data[(idx + 3) as usize]
);
dtcs.push(MultiType::Str(dtc));
idx += 4;
}
ecu.insert("DTC信息".to_string(), MultiType::Vec(dtcs));
ecu_list.push(MultiType::Map(ecu));
}
map.insert("ECU列表".to_string(), MultiType::Vec(ecu_list));
map
}
pub fn parse_alarm(&self, data: &[&str], start_char: &str) -> ParseResult {
let mut map = HashMap::new();
let alarm_level = self.alarm_level.get(data[1]).unwrap_or(&"未知");
map.insert(
"最高报警等级".to_string(),
MultiType::Str(alarm_level.to_string()),
);
let alarm_flag_hex = format!("{}{}{}{}", data[2], data[3], data[4], data[5]);
let alarm_flag = self.hex2long(&alarm_flag_hex);
let mut alarm_bits = HashMap::new();
alarm_bits.insert(
"温度差异".to_string(),
MultiType::Str(self.get_general_alarm_dec(0x0, alarm_flag as u64)),
);
alarm_bits.insert(
"电池高温".to_string(),
MultiType::Str(self.get_general_alarm_dec(0x1, alarm_flag as u64)),
);
alarm_bits.insert(
"车载储能装置类型过压".to_string(),
MultiType::Str(self.get_general_alarm_dec(0x2, alarm_flag as u64)),
);
alarm_bits.insert(
"车载储能装置类型欠压".to_string(),
MultiType::Str(self.get_general_alarm_dec(0x3, alarm_flag as u64)),
);
alarm_bits.insert(
"SOC低".to_string(),
MultiType::Str(self.get_general_alarm_dec(0x4, alarm_flag as u64)),
);
alarm_bits.insert(
"单体电池过压".to_string(),
MultiType::Str(self.get_general_alarm_dec(0x5, alarm_flag as u64)),
);
alarm_bits.insert(
"单体电池欠压".to_string(),
MultiType::Str(self.get_general_alarm_dec(0x6, alarm_flag as u64)),
);
alarm_bits.insert(
"SOC过高".to_string(),
MultiType::Str(self.get_general_alarm_dec(0x7, alarm_flag as u64)),
);
alarm_bits.insert(
"SOC跳变".to_string(),
MultiType::Str(self.get_general_alarm_dec(0x8, alarm_flag as u64)),
);
alarm_bits.insert(
"可充电储能系统不匹配".to_string(),
MultiType::Str(self.get_general_alarm_dec(0x9, alarm_flag as u64)),
);
alarm_bits.insert(
"电池单体一致性差".to_string(),
MultiType::Str(self.get_general_alarm_dec(0xa, alarm_flag as u64)),
);
alarm_bits.insert(
"绝缘".to_string(),
MultiType::Str(self.get_general_alarm_dec(0xb, alarm_flag as u64)),
);
alarm_bits.insert(
"DC-DC温度".to_string(),
MultiType::Str(self.get_general_alarm_dec(0xc, alarm_flag as u64)),
);
alarm_bits.insert(
"制动系统".to_string(),
MultiType::Str(self.get_general_alarm_dec(0xd, alarm_flag as u64)),
);
alarm_bits.insert(
"驱动电机控制器温度".to_string(),
MultiType::Str(self.get_general_alarm_dec(0xe, alarm_flag as u64)),
);
alarm_bits.insert(
"高压互锁状态".to_string(),
MultiType::Str(self.get_general_alarm_dec(0xf, alarm_flag as u64)),
);
alarm_bits.insert(
"驱动电机温度".to_string(),
MultiType::Str(self.get_general_alarm_dec(0x10, alarm_flag as u64)),
);
alarm_bits.insert(
"车载储能装置类型过充".to_string(),
MultiType::Str(self.get_general_alarm_dec(0x11, alarm_flag as u64)),
);
map.insert("通用报警标志".to_string(), MultiType::Map(alarm_bits));
let mut idx = 6;
let energy_fault_count = self.get_val_byte(data[idx], 1.0, 0);
map.insert(
"可充电储能装置故障总数".to_string(),
MultiType::Str(energy_fault_count.clone()),
);
let energy_fault_count_int = self.hex2integer_e(energy_fault_count);
let mut energy_fault_list = Vec::new();
if idx >= data.len() {
return ParseResult {
length: idx - 1,
data: map,
};
}
idx += 1;
for i in 0..energy_fault_count_int {
if idx + 3 >= data.len() || i >= 0xff {
return ParseResult {
length: idx - 1,
data: map,
};
}
let fault_code = format!(
"{}{}{}{}",
data[idx],
data[idx + 1],
data[idx + 2],
data[idx + 3]
);
energy_fault_list.push(MultiType::Str(fault_code));
idx += 4;
}
map.insert(
"可充电储能装置故障码列表".to_string(),
MultiType::Vec(energy_fault_list),
);
if idx >= data.len() {
return ParseResult {
length: idx - 1,
data: map,
};
}
let drive_motor_fault_count = self.get_val_byte(data[idx], 1.0, 0);
map.insert(
"驱动电机故障总数".to_string(),
MultiType::Str(drive_motor_fault_count.clone()),
);
let drive_motor_fault_count_int = self.hex2integer_e(drive_motor_fault_count);
let mut drive_motor_fault_list = Vec::new();
idx += 1;
for i in 0..drive_motor_fault_count_int {
if idx + 3 >= data.len() || i >= 0xff {
return ParseResult {
length: idx - 1,
data: map,
};
}
let fault_code = format!(
"{}{}{}{}",
data[idx],
data[idx + 1],
data[idx + 2],
data[idx + 3]
);
drive_motor_fault_list.push(MultiType::Str(fault_code));
idx += 4;
}
map.insert(
"驱动电机故障码列表".to_string(),
MultiType::Vec(drive_motor_fault_list),
);
if idx >= data.len() {
return ParseResult {
length: idx - 1,
data: map,
};
}
let engine_fault_count = self.get_val_byte(data[idx], 1.0, 0);
map.insert(
"发动机故障总数".to_string(),
MultiType::Str(engine_fault_count.clone()),
);
let engine_fault_count_int = self.hex2integer_e(engine_fault_count);
let mut engine_fault_list = Vec::new();
idx += 1;
for i in 0..engine_fault_count_int {
if idx + 3 >= data.len() || i >= 0xff {
return ParseResult {
length: idx - 1,
data: map,
};
}
let fault_code = format!(
"{}{}{}{}",
data[idx],
data[idx + 1],
data[idx + 2],
data[idx + 3]
);
engine_fault_list.push(MultiType::Str(fault_code));
idx += 4;
}
map.insert(
"发动机故障码列表".to_string(),
MultiType::Vec(engine_fault_list),
);
if idx >= data.len() {
return ParseResult {
length: idx - 1,
data: map,
};
}
let other_fault_count = self.get_val_byte(data[idx], 1.0, 0);
map.insert(
"其他故障总数".to_string(),
MultiType::Str(other_fault_count.clone()),
);
let other_fault_count_int = self.hex2integer_e(other_fault_count);
let mut other_fault_list = Vec::new();
idx += 1;
for i in 0..other_fault_count_int {
if idx + 3 >= data.len() || i >= 0xff {
return ParseResult {
length: idx - 1,
data: map,
};
}
let fault_code = format!(
"{}{}{}{}",
data[idx],
data[idx + 1],
data[idx + 2],
data[idx + 3]
);
other_fault_list.push(MultiType::Str(fault_code));
idx += 4;
}
map.insert(
"其他故障码列表".to_string(),
MultiType::Vec(other_fault_list),
);
if start_char == "$$" && idx < data.len() {
let common_fault_count = self.get_val_byte(data[idx], 1.0, 0);
map.insert(
"通用报警故障总数".to_string(),
MultiType::Str(common_fault_count.clone()),
);
let common_fault_count_int = self.hex2integer_e(common_fault_count);
let mut common_fault_list = Vec::new();
idx += 1;
for i in 0..common_fault_count_int {
if idx + 1 >= data.len() || i >= 0xff {
return ParseResult {
length: idx - 1,
data: map,
};
}
let fault_level = format!("{}{}", data[idx], data[idx + 1]);
common_fault_list.push(MultiType::Str(fault_level));
idx += 2;
}
map.insert(
"通用报警故障等级列表".to_string(),
MultiType::Vec(common_fault_list),
);
}
ParseResult {
length: idx - 1,
data: map,
}
}
pub fn parse_voltage(&self, data: &[&str]) -> ParseResult {
let mut map = HashMap::new();
let sub_count_str = self.get_val_byte(data[1], 1.0, 0);
map.insert(
"可充电储能子系统个数".to_string(),
MultiType::Str(sub_count_str.clone()),
);
let sub_count = self.hex2integer_e(sub_count_str);
let mut subs = Vec::new();
let mut idx = 2;
for _ in 0..sub_count {
if idx + 5 > data.len() as i32 {
break;
}
let mut sub = HashMap::new();
sub.insert(
"可充电储能子系统号".to_string(),
MultiType::Str(self.get_val_byte(data[idx as usize], 1.0, 0)),
);
sub.insert(
"可充电储能装置电压".to_string(),
MultiType::Str(self.get_float_word(
data[(idx + 1) as usize],
data[(idx + 2) as usize],
0.1,
0,
1,
)),
);
sub.insert(
"可充电储能装置电流".to_string(),
MultiType::Str(self.get_float_word(
data[(idx + 3) as usize],
data[(idx + 4) as usize],
0.1,
-1000,
1,
)),
);
let cell_count_str =
self.get_val_word(data[(idx + 5) as usize], data[(idx + 6) as usize], 1.0, 0);
sub.insert(
"单体电池总数".to_string(),
MultiType::Str(cell_count_str.clone()),
);
sub.insert(
"本帧起始电池序号".to_string(),
MultiType::Str(self.get_val_word(
data[(idx + 7) as usize],
data[(idx + 8) as usize],
1.0,
0,
)),
);
let frame_cell_count_str = self.get_val_byte(data[(idx + 9) as usize], 1.0, 0);
sub.insert(
"本帧单体电池总数".to_string(),
MultiType::Str(frame_cell_count_str.clone()),
);
let frame_cell_count = self.hex2integer_e(frame_cell_count_str);
let mut cells = Vec::new();
idx += 10;
for j in 0..frame_cell_count {
if idx + 1 >= data.len() as i32 {
break;
}
let cell_voltage =
self.get_val_word(data[idx as usize], data[(idx + 1) as usize], 0.001, 0);
let mut cell_map = HashMap::new();
cell_map.insert((j + 1).to_string(), MultiType::Str(cell_voltage));
cells.push(MultiType::Map(cell_map));
idx += 2;
}
sub.insert("单体电池电压列表".to_string(), MultiType::Vec(cells));
subs.push(MultiType::Map(sub));
}
map.insert(
"可充电储能子系统电压信息列表".to_string(),
MultiType::Vec(subs),
);
ParseResult {
length: idx as usize - 1,
data: map,
}
}
pub fn parse_newenergy(&self, data: &[&str]) -> HashMap<String, MultiType> {
let mut map = HashMap::new();
map.insert("原始数据".to_string(), MultiType::Str(data.join(" ")));
map
}
pub fn parse_alarmlevel(&self, data: &[&str]) -> HashMap<String, MultiType> {
let mut map = HashMap::new();
map.insert("报警等级".to_string(), MultiType::Str(data[1].to_string()));
let mut idx = 2;
let mut levels = Vec::new();
while idx + 1 < data.len() {
let code = format!("{}{}", data[idx], data[idx + 1]);
levels.push(MultiType::Str(code));
idx += 2;
}
map.insert("报警等级码列表".to_string(), MultiType::Vec(levels));
map
}
pub fn parse_realtime(&self, data: &[&str], start_char: &str) -> HashMap<String, MultiType> {
let mut map = HashMap::new();
if data.len() < 6 {
return map;
}
map.insert(
"数据采集时间".to_string(),
MultiType::Str(self.get_time(data[0], data[1], data[2], data[3], data[4], data[5])),
);
let mut idx = 6;
while idx < data.len() {
let dtype = data[idx];
if idx + 1 >= data.len() {
break;
}
match dtype {
"01" => {
let mut vehicle_data = vec![];
let mut temp_idx = idx;
while temp_idx < data.len() {
vehicle_data.push(data[temp_idx]);
temp_idx += 1;
}
let vehicle = self.parse_vehicle(&vehicle_data, start_char);
map.insert("整车数据".to_string(), MultiType::Map(vehicle.data));
idx = idx + 1 + vehicle.length;
}
"02" => {
let mut motors_data = vec![];
let mut temp_idx = idx;
while temp_idx < data.len() {
motors_data.push(data[temp_idx]);
temp_idx += 1;
}
let motors = self.parse_motors(&motors_data, start_char);
map.insert("驱动电机数据".to_string(), MultiType::Map(motors.data));
idx = idx + 1 + motors.length;
}
"03" => {
let mut fuel_data = vec![];
let mut temp_idx = idx;
while temp_idx < data.len() {
fuel_data.push(data[temp_idx]);
temp_idx += 1;
}
let fuel = self.parse_fuelcell(&fuel_data);
map.insert("燃料电池数据".to_string(), MultiType::Map(fuel.data));
idx = idx + fuel.length + 1;
}
"04" => {
let mut engine_data = vec![];
let mut temp_idx = idx;
while temp_idx < data.len() {
engine_data.push(data[temp_idx]);
temp_idx += 1;
}
let engine = self.parse_engine(&engine_data);
map.insert("发动机数据".to_string(), MultiType::Map(engine.data));
idx = idx + engine.length + 1;
}
"05" => {
let mut position_data = vec![];
let mut temp_idx = idx;
while temp_idx < data.len() {
position_data.push(data[temp_idx]);
temp_idx += 1;
}
let position = self.parse_position(&position_data, start_char);
map.insert("车辆位置数据".to_string(), MultiType::Map(position.data));
idx = idx + position.length + 1;
}
"06" => {
if start_char == "##" {
let mut extremum_data = vec![];
let mut temp_idx = idx;
while temp_idx < data.len() {
extremum_data.push(data[temp_idx]);
temp_idx += 1;
}
let extremum = self.parse_extremum(&extremum_data);
map.insert("极值数据".to_string(), MultiType::Map(extremum.data));
idx = idx + extremum.length + 1;
}
if start_char == "$$" {
let mut alarm_data = vec![];
let mut temp_idx = idx;
while temp_idx < data.len() {
alarm_data.push(data[temp_idx]);
temp_idx += 1;
}
let alarm = self.parse_alarm(&alarm_data, start_char);
map.insert("报警数据".to_string(), MultiType::Map(alarm.data));
idx = idx + alarm.length + 1;
}
}
"07" => {
if start_char == "##" {
let mut alarm_data = vec![];
let mut temp_idx = idx;
while temp_idx < data.len() {
alarm_data.push(data[temp_idx]);
temp_idx += 1;
}
let alarm = self.parse_alarm(&alarm_data, start_char);
map.insert("报警数据".to_string(), MultiType::Map(alarm.data));
idx = idx + alarm.length + 1;
}
if start_char == "$$" {
let mut voltage_data = vec![];
let mut temp_idx = idx;
while temp_idx < data.len() {
voltage_data.push(data[temp_idx]);
temp_idx += 1;
}
let voltage = self.parse_battery_min_parallel_voltage_2025(&voltage_data);
map.insert(
"动力蓄电池最小并联单元电压数据".to_string(),
MultiType::Map(voltage.data),
);
idx = idx + voltage.length + 1;
}
}
"08" => {
if start_char == "##" {
let mut voltage_data = vec![];
let mut temp_idx = idx;
while temp_idx < data.len() {
voltage_data.push(data[temp_idx]);
temp_idx += 1;
}
let voltage = self.parse_voltage(&voltage_data);
map.insert(
"可充电储能装置电压数据".to_string(),
MultiType::Map(voltage.data),
);
idx = idx + voltage.length + 1;
}
if start_char == "$$" {
let mut temp_data = vec![];
let mut temp_idx = idx;
while temp_idx < data.len() {
temp_data.push(data[temp_idx]);
temp_idx += 1;
}
let temp = self.parse_temp_2025(&temp_data);
map.insert("动力蓄电池温度数据".to_string(), MultiType::Map(temp.data));
idx = idx + temp.length + 1;
}
}
"09" => {
if start_char == "##" {
let mut temp_data = vec![];
let mut temp_idx = idx;
while temp_idx < data.len() {
temp_data.push(data[temp_idx]);
temp_idx += 1;
}
let temp = self.parse_temp(&temp_data);
map.insert(
"可充电储能装置温度数据".to_string(),
MultiType::Map(temp.data),
);
idx = idx + temp.length + 1;
} else {
let mut tmp_data = vec![];
let mut tmp_idx = idx;
while tmp_idx < data.len() {
tmp_data.push(MultiType::Str(data[tmp_idx].to_string()));
tmp_idx += 1;
}
map.insert("未知数据".to_string(), MultiType::Vec(tmp_data));
}
}
"30" => {
if start_char == "$$" {
let mut fuel_cell_stack_data = vec![];
let mut fuel_cell_stack_idx = idx;
while fuel_cell_stack_idx < data.len() {
fuel_cell_stack_data.push(data[fuel_cell_stack_idx]);
fuel_cell_stack_idx += 1;
}
let fuel_cell_stack = self.parse_fuel_cell_stack(&fuel_cell_stack_data);
map.insert(
"燃料电池电堆数据".to_string(),
MultiType::Map(fuel_cell_stack.data),
);
idx = idx + fuel_cell_stack.length + 1;
} else {
let mut tmp_data = vec![];
let mut tmp_idx = idx;
while tmp_idx < data.len() {
tmp_data.push(MultiType::Str(data[tmp_idx].to_string()));
tmp_idx += 1;
}
map.insert("未知数据".to_string(), MultiType::Vec(tmp_data));
idx = data.len(); }
}
"31" => {
if start_char == "$$" {
let mut super_electric_container_data = vec![];
let mut super_electric_container_idx = idx;
while super_electric_container_idx < data.len() {
super_electric_container_data.push(data[super_electric_container_idx]);
super_electric_container_idx += 1;
}
let super_electric_container =
self.parse_super_electric_container(&super_electric_container_data);
map.insert(
"超级电容器数据".to_string(),
MultiType::Map(super_electric_container.data),
);
idx = idx + super_electric_container.length + 1;
} else {
let mut tmp_data = vec![];
let mut tmp_idx = idx;
while tmp_idx < data.len() {
tmp_data.push(MultiType::Str(data[tmp_idx].to_string()));
tmp_idx += 1;
}
map.insert("未知数据".to_string(), MultiType::Vec(tmp_data));
idx = data.len(); }
}
"32" => {
if start_char == "$$" {
let mut super_electric_container_extreme_values_data = vec![];
let mut super_electric_container_extreme_values_idx = idx;
while super_electric_container_extreme_values_idx < data.len() {
super_electric_container_extreme_values_data
.push(data[super_electric_container_extreme_values_idx]);
super_electric_container_extreme_values_idx += 1;
}
let super_electric_container_extreme_values = self
.parse_super_electric_container_extreme_values(
&super_electric_container_extreme_values_data,
);
map.insert(
"超级电容器极值数据".to_string(),
MultiType::Map(super_electric_container_extreme_values.data),
);
idx = idx + super_electric_container_extreme_values.length + 1;
} else {
let mut tmp_data = vec![];
let mut tmp_idx = idx;
while tmp_idx < data.len() {
tmp_data.push(MultiType::Str(data[tmp_idx].to_string()));
tmp_idx += 1;
}
map.insert("未知数据".to_string(), MultiType::Vec(tmp_data));
idx = data.len(); }
}
_ => {
let mut tmp_data = vec![];
let mut tmp_idx = idx;
while tmp_idx < data.len() {
tmp_data.push(MultiType::Str(data[tmp_idx].to_string()));
tmp_idx += 1;
}
map.insert("未知数据".to_string(), MultiType::Vec(tmp_data));
idx = data.len(); }
}
}
map
}
fn parse_reissue(&self, data: &[&str], start_char: &str) -> HashMap<String, MultiType> {
self.parse_realtime(data, start_char)
}
fn parse_reg(&self, data: &[&str]) -> HashMap<String, MultiType> {
let mut map = HashMap::new();
if data.len() < 30 {
return map;
}
let time = self.get_time(data[0], data[1], data[2], data[3], data[4], data[5]);
map.insert("数据采集时间".to_string(), MultiType::Str(time));
let tbox_len = self.hex2int(data[6]);
map.insert(
"TBOX编号长度".to_string(),
MultiType::Str(tbox_len.to_string()),
);
let mut tbox = String::new();
for i in 0..tbox_len as usize {
if 7 + i < data.len() {
tbox.push_str(data[7 + i]);
}
}
map.insert("TBOX编号".to_string(), MultiType::Str(tbox));
map.insert("ICCID长度".to_string(), MultiType::Str("20".to_string()));
let mut iccid = String::new();
for i in 0..20 {
if 7 + tbox_len as usize + i < data.len() {
iccid.push_str(data[7 + tbox_len as usize + i]);
}
}
map.insert("ICCID".to_string(), MultiType::Str(iccid));
let imei_len = self.hex2int(data[7 + tbox_len as usize + 20]);
map.insert("IMEI长度".to_string(), MultiType::Str(imei_len.to_string()));
let mut imei = String::new();
for i in 0..imei_len as usize {
if 8 + tbox_len as usize + 20 + i < data.len() {
imei.push_str(data[8 + tbox_len as usize + 20 + i]);
}
}
map.insert("IMEI".to_string(), MultiType::Str(imei));
let fw_len = self.hex2int(data[8 + tbox_len as usize + 20 + imei_len as usize]);
map.insert(
"自定义固件版本长度".to_string(),
MultiType::Str(fw_len.to_string()),
);
let mut firmware = String::new();
for i in 0..fw_len as usize {
if 9 + tbox_len as usize + 20 + imei_len as usize + i < data.len() {
firmware.push_str(data[9 + tbox_len as usize + 20 + imei_len as usize + i]);
}
}
map.insert("固件版本号".to_string(), MultiType::Str(firmware));
let hw_len =
self.hex2int(data[9 + tbox_len as usize + 20 + imei_len as usize + fw_len as usize]);
map.insert(
"自定义硬件版本长度".to_string(),
MultiType::Str(hw_len.to_string()),
);
let mut hardware = String::new();
for i in 0..hw_len as usize {
if 10 + tbox_len as usize + 20 + imei_len as usize + fw_len as usize + i < data.len() {
hardware.push_str(
data[10 + tbox_len as usize + 20 + imei_len as usize + fw_len as usize + i],
);
}
}
map.insert("硬件版本号".to_string(), MultiType::Str(hardware));
map
}
pub fn decode(&self, hex_str: &str) -> HashMap<String, MultiType> {
let mut result = HashMap::new();
let formatted = self.format_hex(hex_str);
if formatted.is_empty() {
return result;
}
let valid = formatted
.split_whitespace()
.all(|s| s.len() == 2 && s.chars().all(|c| c.is_ascii_hexdigit()));
if !valid {
return result;
}
let arr: Vec<&str> = formatted.split_whitespace().collect();
if arr.len() < 24 {
return result;
}
if !((arr[0] == "23" && arr[1] == "23") || (arr[0] == "24" && arr[1] == "24")) {
return result;
}
let start_char = format!(
"{}{}",
char::from(self.hex2int(arr[0]) as u8),
char::from(self.hex2int(arr[1]) as u8)
);
result.insert("起始符".to_string(), MultiType::Str(start_char.clone()));
let cmd_id = arr[2];
let ack_id = arr[3];
let cmd_type = self.data_type.get(cmd_id).unwrap_or(&"未知").to_string();
let ack_type = self
.data_type_ack
.get(ack_id)
.unwrap_or(&"未知")
.to_string();
let mut cmd_map = HashMap::new();
cmd_map.insert("命令标识".to_string(), MultiType::Str(cmd_type.clone()));
cmd_map.insert("应答标志".to_string(), MultiType::Str(ack_type));
result.insert("命令单元".to_string(), MultiType::Map(cmd_map));
let unique: String = arr[4..21]
.iter()
.map(|x| char::from(self.hex2int(x) as u8))
.collect();
result.insert("唯一识别码".to_string(), MultiType::Str(unique));
let encrypt = self.encrypt_type.get(arr[21]).unwrap_or(&"未知");
result.insert(
"数据单元加密方式".to_string(),
MultiType::Str(encrypt.to_string()),
);
let data_len = if arr.len() > 23 {
let len = format!("{}{}", arr[22], arr[23]);
self.hex2int(&len)
} else {
0
};
result.insert("数据单元长度".to_string(), MultiType::Int(data_len as i64));
if arr.len() > 24 {
let data_unit: Vec<&str> = arr[24..arr.len() - 1].to_vec();
if cmd_type == "车辆登录" {
let login_map = self.parse_login(&data_unit);
let mut data_map = HashMap::new();
data_map.insert("车辆登录".to_string(), MultiType::Map(login_map));
result.insert("数据单元内容".to_string(), MultiType::Map(data_map));
} else if cmd_type == "车辆登出" {
let logout_map = self.parse_logout(&data_unit);
let mut data_map = HashMap::new();
data_map.insert("车辆登出".to_string(), MultiType::Map(logout_map));
result.insert("数据单元内容".to_string(), MultiType::Map(data_map));
} else if cmd_type == "实时信息上报" {
let rt_map = self.parse_realtime(&data_unit, &start_char);
let mut rt_content = HashMap::new();
rt_content.insert(cmd_type.clone(), MultiType::Map(rt_map));
result.insert("数据单元内容".to_string(), MultiType::Map(rt_content));
} else if cmd_type == "补发信息上报" {
let reissue_map = self.parse_reissue(&data_unit, &start_char);
let mut reissue_content = HashMap::new();
reissue_content.insert(cmd_type.clone(), MultiType::Map(reissue_map));
result.insert("数据单元内容".to_string(), MultiType::Map(reissue_content));
} else if cmd_type == "DTC数据上报" {
let reissue_map = self.parse_dtc(&data_unit);
let mut reissue_content = HashMap::new();
reissue_content.insert(cmd_type.clone(), MultiType::Map(reissue_map));
result.insert("数据单元内容".to_string(), MultiType::Map(reissue_content));
} else if cmd_type == "T-BOX注册" {
let reissue_map = self.parse_reg(&data_unit);
let mut reissue_content = HashMap::new();
reissue_content.insert(cmd_type.clone(), MultiType::Map(reissue_map));
result.insert("数据单元内容".to_string(), MultiType::Map(reissue_content));
} else if cmd_type == "升级结果状态上报" {
let reissue_map = self.parse_ota_res_rep(&data_unit);
let mut reissue_content = HashMap::new();
reissue_content.insert(cmd_type.clone(), MultiType::Map(reissue_map));
result.insert("数据单元内容".to_string(), MultiType::Map(reissue_content));
} else if cmd_type == "ECU升级结果" {
let reissue_map = self.parse_ecu_ota_res_rep(&data_unit);
let mut reissue_content = HashMap::new();
reissue_content.insert(cmd_type.clone(), MultiType::Map(reissue_map));
result.insert("数据单元内容".to_string(), MultiType::Map(reissue_content));
} else if cmd_type == "ECU信息查询" {
let reissue_map = self.parse_ecu_query(&data_unit);
let mut reissue_content = HashMap::new();
reissue_content.insert(cmd_type.clone(), MultiType::Map(reissue_map));
result.insert("数据单元内容".to_string(), MultiType::Map(reissue_content));
} else {
result.insert(
"数据单元内容".to_string(),
MultiType::Vec(
data_unit
.iter()
.map(|unit| MultiType::Str((*unit).to_string()))
.collect(),
),
);
}
}
result
}
pub fn parse_extremum(&self, data: &[&str]) -> ParseResult {
let mut map = HashMap::new();
let high_voltage_subsys = self.get_val_byte(data[1], 1.0, 0);
map.insert(
"最高电压电池子系统号".to_string(),
MultiType::Str(high_voltage_subsys.to_string()),
);
let high_voltage_cell = self.get_val_byte(data[2], 1.0, 0);
map.insert(
"最高电压电池单体代号".to_string(),
MultiType::Str(high_voltage_cell.to_string()),
);
let high_voltage = self.get_val_word(data[3], data[4], 0.001, 0);
map.insert(
"电池单体电压最高值".to_string(),
MultiType::Str(high_voltage),
);
let low_voltage_subsys = self.get_val_byte(data[5], 1.0, 0);
map.insert(
"最低电压电池子系统号".to_string(),
MultiType::Str(low_voltage_subsys.to_string()),
);
let low_voltage_cell = self.get_val_byte(data[6], 1.0, 0);
map.insert(
"最低电压电池单体代号".to_string(),
MultiType::Str(low_voltage_cell.to_string()),
);
let low_voltage = self.get_val_word(data[7], data[8], 0.001, 0);
map.insert(
"电池单体电压最低值".to_string(),
MultiType::Str(low_voltage),
);
let high_temp_subsys = self.get_val_byte(data[9], 1.0, 0);
map.insert(
"最高温度子系统号".to_string(),
MultiType::Str(high_temp_subsys.to_string()),
);
let high_temp_probe = self.get_val_byte(data[10], 1.0, 0);
map.insert(
"最高温度探针序号".to_string(),
MultiType::Str(high_temp_probe.to_string()),
);
let high_temp_i32 = self.get_val_byte(data[11], 1.0, -40);
map.insert(
"最高温度值".to_string(),
MultiType::Str(high_temp_i32.to_string()),
);
let low_temp_subsys = self.hex2int(data[12]);
map.insert(
"最低温度子系统号".to_string(),
MultiType::Str(low_temp_subsys.to_string()),
);
let low_temp_probe = self.hex2int(data[13]);
map.insert(
"最低温度探针序号".to_string(),
MultiType::Str(low_temp_probe.to_string()),
);
let low_temp_i32 = self.get_val_byte(data[14], 1.0, -40);
map.insert(
"最低温度".to_string(),
MultiType::Str(low_temp_i32.to_string()),
);
ParseResult {
length: 14,
data: map,
}
}
pub fn parse_supercapacitor(&self, data: &[&str]) -> HashMap<String, MultiType> {
let mut map = HashMap::new();
let mut idx = 0;
if data.len() < 7 {
map.insert("原始数据".to_string(), MultiType::Str(data.join(" ")));
return map;
}
map.insert(
"超级电容器管理系统号".to_string(),
MultiType::Str(data[idx].to_string()),
);
idx += 1;
if idx + 1 < data.len() {
let v = (self.hex2int(data[idx]) << 8 | self.hex2int(data[idx + 1])) as f32 * 0.1;
map.insert(
"超级电容器总电压".to_string(),
MultiType::Str(format!("{:.1}", v)),
);
idx += 2;
}
if idx + 1 < data.len() {
let a =
(self.hex2int(data[idx]) << 8 | self.hex2int(data[idx + 1])) as f32 * 0.1 - 3000.0;
map.insert(
"超级电容器总电流".to_string(),
MultiType::Str(format!("{:.1}", a)),
);
idx += 2;
}
let mut cell_count = 0;
if idx + 1 < data.len() {
cell_count = (self.hex2int(data[idx]) << 8 | self.hex2int(data[idx + 1])) as usize;
map.insert(
"超级电容器单体总数".to_string(),
MultiType::Str(cell_count.to_string()),
);
idx += 2;
}
let mut voltages = Vec::new();
for _ in 0..cell_count {
if idx + 1 >= data.len() {
break;
}
let v = (self.hex2int(data[idx]) << 8 | self.hex2int(data[idx + 1])) as f32 * 0.001;
voltages.push(MultiType::Str(format!("{:.3}", v)));
idx += 2;
}
map.insert("超级电容器单体电压".to_string(), MultiType::Vec(voltages));
let mut probe_count = 0;
if idx + 1 < data.len() {
probe_count = (self.hex2int(data[idx]) << 8 | self.hex2int(data[idx + 1])) as usize;
map.insert(
"超级电容器温度探针总数".to_string(),
MultiType::Str(probe_count.to_string()),
);
idx += 2;
}
let mut temps = Vec::new();
for _ in 0..probe_count {
if idx >= data.len() {
break;
}
let t = self.hex2int(data[idx]) as i32 - 40;
temps.push(t.to_string());
idx += 1;
}
map.insert(
"超级电容器探针温度".to_string(),
MultiType::Str(temps.join(",")),
);
map
}
pub fn parse_supercapacitor_extremum(&self, data: &[&str]) -> HashMap<String, MultiType> {
let mut map = HashMap::new();
if data.len() < 15 {
map.insert("原始数据".to_string(), MultiType::Str(data.join(" ")));
return map;
}
map.insert(
"最高电压子系统号".to_string(),
MultiType::Str(data[1].to_string()),
);
map.insert(
"最高电压单体代号".to_string(),
MultiType::Str(data[2].to_string()),
);
map.insert(
"单体电压最高值".to_string(),
MultiType::Str(format!("{}{}", data[3], data[4])),
);
map.insert(
"最低电压子系统号".to_string(),
MultiType::Str(data[5].to_string()),
);
map.insert(
"最低电压单体代号".to_string(),
MultiType::Str(data[6].to_string()),
);
map.insert(
"单体电压最低值".to_string(),
MultiType::Str(format!("{}{}", data[7], data[8])),
);
map.insert(
"最高温度子系统号".to_string(),
MultiType::Str(data[9].to_string()),
);
map.insert(
"最高温度探针序号".to_string(),
MultiType::Str(data[10].to_string()),
);
map.insert("最高温度".to_string(), MultiType::Str(data[11].to_string()));
map.insert(
"最低温度子系统号".to_string(),
MultiType::Str(data[12].to_string()),
);
map.insert(
"最低温度探针序号".to_string(),
MultiType::Str(data[13].to_string()),
);
map.insert("最低温度".to_string(), MultiType::Str(data[14].to_string()));
map
}
pub fn parse_temp(&self, data: &[&str]) -> ParseResult {
let mut map = HashMap::new();
let sub_count = if data[1] != "FE" && data[1] != "FF" {
self.hex2int(data[1])
} else {
0
};
map.insert(
"可充电储能子系统数".to_string(),
MultiType::Int(sub_count as i64),
);
let mut subs = Vec::new();
let mut idx = 2;
for _ in 0..sub_count {
if idx + 2 > data.len() as i32 {
break;
}
let mut sub = HashMap::new();
if idx < data.len() as i32 {
sub.insert(
"可充电储能子系统号".to_string(),
MultiType::Str(self.get_val_byte(data[idx as usize], 1.0, 0)),
);
}
if idx + 1 < data.len() as i32 {
let temp_count_str =
self.get_val_word(data[(idx + 1) as usize], data[(idx + 2) as usize], 1.0, 0);
sub.insert(
"可充电储能温度探针个数".to_string(),
MultiType::Str(temp_count_str.clone()),
);
let temp_count = self.hex2integer_e(temp_count_str);
let mut temps = Vec::new();
idx += 3;
for _ in 0..temp_count {
if idx >= data.len() as i32 {
break;
}
temps.push(MultiType::Str(self.get_val_byte(
data[idx as usize],
1.0,
-40,
)));
idx += 1;
}
sub.insert("单体温度".to_string(), MultiType::Vec(temps));
}
subs.push(MultiType::Map(sub));
}
map.insert(
"可充电储能子系统各温度探针检测到的温度值".to_string(),
MultiType::Vec(subs),
);
ParseResult {
length: idx as usize - 1,
data: map,
}
}
pub fn parse_temp_2025(&self, data: &[&str]) -> ParseResult {
let mut map = HashMap::new();
let sub_count = if data[1] != "FE" && data[1] != "FF" {
self.hex2int(data[1])
} else {
0
};
if sub_count > 0 {
map.insert(
"动力蓄电池包个数".to_string(),
MultiType::Int(sub_count as i64),
);
} else {
map.insert(
"动力蓄电池包个数".to_string(),
MultiType::Str(self.get_val_byte(data[1], 1.0, 0)),
);
}
let mut subs = Vec::new();
let mut idx = 2;
for _ in 0..sub_count {
if idx + 2 > data.len() as i32 {
break;
}
let mut sub = HashMap::new();
if idx < data.len() as i32 {
sub.insert(
"动力蓄电池包号".to_string(),
MultiType::Str(self.get_val_byte(data[idx as usize], 1.0, 0)),
);
}
if idx + 1 < data.len() as i32 {
let temp_count_str =
self.get_val_word(data[(idx + 1) as usize], data[(idx + 2) as usize], 1.0, 0);
sub.insert(
"动力蓄电池包温度探针个数".to_string(),
MultiType::Str(temp_count_str.clone()),
);
let temp_count = self.hex2integer_e(temp_count_str);
let mut temps = Vec::new();
idx += 3;
for _ in 0..temp_count {
if idx >= data.len() as i32 {
break;
}
temps.push(MultiType::Str(self.get_val_byte(
data[idx as usize],
1.0,
-40,
)));
idx += 1;
}
sub.insert(
"各温度探针检测到的温度值".to_string(),
MultiType::Vec(temps),
);
}
subs.push(MultiType::Map(sub));
}
map.insert("动力蓄电池温度信息列表".to_string(), MultiType::Vec(subs));
ParseResult {
length: idx as usize - 1,
data: map,
}
}
fn parse_fuel_cell_stack(&self, data: &[&str]) -> ParseResult {
let mut idx = 2;
let count = self.hex2int(data[1]) as usize;
let mut map = HashMap::new();
map.insert("燃料电池电堆个数".to_string(), MultiType::Int(count as i64));
let mut fuel_cell_stacks = vec![];
for _ in 0..count {
if idx >= data.len() {
break;
}
let mut fuel_cell_stack = HashMap::new();
fuel_cell_stack.insert(
"燃料电池电堆序号".to_string(),
MultiType::Str(self.get_val_byte(data[idx], 1.0, 0)),
);
idx += 1;
fuel_cell_stack.insert(
"燃料电池电堆电压".to_string(),
MultiType::Str(self.get_val_word(data[idx], data[idx + 1], 0.1, 0)),
);
idx += 2;
fuel_cell_stack.insert(
"燃料电池电堆电流".to_string(),
MultiType::Str(self.get_val_word(data[idx], data[idx + 1], 0.1, 0)),
);
idx += 2;
fuel_cell_stack.insert(
"氢气入口压力".to_string(),
MultiType::Str(self.get_val_word(data[idx], data[idx + 1], 0.1, -100)),
);
idx += 2;
fuel_cell_stack.insert(
"空气入口压力".to_string(),
MultiType::Str(self.get_val_word(data[idx], data[idx + 1], 0.1, -100)),
);
idx += 2;
fuel_cell_stack.insert(
"空气入口温度".to_string(),
MultiType::Str(self.get_val_byte(data[idx], 1.0, -40)),
);
idx += 1;
let cold_air_temperature_count = self.get_val_word(data[idx], data[idx + 1], 1.0, 0);
fuel_cell_stack.insert(
"冷却水出水口温度探针总数".to_string(),
MultiType::Str(cold_air_temperature_count.clone()),
);
idx += 2;
let cold_air_temperature_count_val =
cold_air_temperature_count.parse::<i64>().unwrap_or(0) as usize;
let mut cold_air_temperature_list = vec![];
if idx >= data.len() {
break;
}
for _ in 0..cold_air_temperature_count_val {
if idx >= data.len() {
break;
}
cold_air_temperature_list
.push(MultiType::Str(self.get_val_byte(data[idx], 1.0, -40)));
idx += 1;
}
fuel_cell_stack.insert(
"冷却水出水口温度".to_string(),
MultiType::Vec(cold_air_temperature_list),
);
fuel_cell_stacks.push(MultiType::Map(fuel_cell_stack));
}
map.insert(
"燃料电池电堆信息表".to_string(),
MultiType::Vec(fuel_cell_stacks),
);
ParseResult {
length: idx - 1,
data: map,
}
}
fn parse_super_electric_container(&self, data: &[&str]) -> ParseResult {
let mut length = 0;
let mut map = HashMap::new();
if data.len() > length {
let value = data[length];
map.insert(
"超级电容器管理系统号".to_string(),
MultiType::Str(self.get_val_byte(value, 1.0, 0)),
);
length += 1;
}
if data.len() > length + 1 {
let voltage = self.get_val_word(data[length], data[length + 1], 0.1, 0);
map.insert("超级电容器总电压".to_string(), MultiType::Str(voltage));
length += 2;
}
if data.len() > length + 1 {
let current = self.get_val_word(data[length], data[length + 1], 0.1, -3000);
map.insert("超级电容器总电流".to_string(), MultiType::Str(current));
length += 2;
}
if data.len() > length + 1 {
let cell_count = self.get_val_word(data[length], data[length + 1], 1.0, 0);
map.insert(
"超级电容器单体总数".to_string(),
MultiType::Str(cell_count.clone()),
);
length += 2;
let cell_count_val = cell_count.parse::<i64>().unwrap_or(0) as usize;
if data.len() > length + (cell_count_val * 2) - 1 {
let mut cell_voltages = vec![];
for _ in 0..cell_count_val {
let cell_voltage = self.get_val_word(data[length], data[length + 1], 0.001, 0);
cell_voltages.push(MultiType::Str(cell_voltage));
length += 2;
}
map.insert(
"超级电容器单体电压".to_string(),
MultiType::Vec(cell_voltages),
);
}
}
if data.len() > length + 1 {
let probe_count = self.get_val_word(data[length], data[length + 1], 1.0, 0);
map.insert(
"超级电容器温度探针总数".to_string(),
MultiType::Str(probe_count.clone()),
);
length += 2;
let probe_count_val = probe_count.parse::<i64>().unwrap_or(0) as usize;
if data.len() > length + probe_count_val - 1 {
let mut probe_temperatures = vec![];
for _ in 0..probe_count_val {
let temperature = self.get_val_byte(data[length], 1.0, -40);
probe_temperatures.push(MultiType::Str(temperature));
length += 1;
}
map.insert("探针温度值".to_string(), MultiType::Vec(probe_temperatures));
}
}
ParseResult { length, data: map }
}
fn parse_super_electric_container_extreme_values(&self, data: &[&str]) -> ParseResult {
let mut length = 0;
let mut map = HashMap::new();
if data.len() > 14 {
length = 14; map.insert(
"超级电容器最高电压电池子系统号".to_string(),
MultiType::Str(self.get_val_byte(data[1], 1.0, 0)),
);
map.insert(
"超级电容器最高电压电池单体代号".to_string(),
MultiType::Str(self.get_val_byte(data[2], 1.0, 0)),
);
map.insert(
"超级电容器电池单体电压最高值(V)".to_string(),
MultiType::Str(self.get_val_word(data[3], data[4], 0.001, 0)),
);
map.insert(
"超级电容器最低电压电池子系统号".to_string(),
MultiType::Str(self.get_val_byte(data[5], 1.0, 0)),
);
map.insert(
"超级电容器最低电压电池单体代号".to_string(),
MultiType::Str(self.get_val_byte(data[6], 1.0, 0)),
);
map.insert(
"超级电容器电池单体电压最低值(V)".to_string(),
MultiType::Str(self.get_val_word(data[7], data[8], 0.001, 0)),
);
map.insert(
"超级电容器最高温度子系统号".to_string(),
MultiType::Str(self.get_val_byte(data[9], 1.0, 0)),
);
map.insert(
"超级电容器最高温度探针序号".to_string(),
MultiType::Str(self.get_val_byte(data[10], 1.0, 0)),
);
map.insert(
"超级电容器最高温度值(℃)".to_string(),
MultiType::Str(self.get_val_byte(data[11], 1.0, -40)),
);
map.insert(
"超级电容器最低温度子系统号".to_string(),
MultiType::Str(self.get_val_byte(data[12], 1.0, 0)),
);
map.insert(
"超级电容器最低温度探针序号".to_string(),
MultiType::Str(self.get_val_byte(data[13], 1.0, 0)),
);
map.insert(
"超级电容器最低温度值(℃)".to_string(),
MultiType::Str(self.get_val_byte(data[14], 1.0, -40)),
);
}
ParseResult { length, data: map }
}
pub fn parse_fuelcell_stack(&self, data: &[&str]) -> HashMap<String, MultiType> {
let mut map = HashMap::new();
if data.len() < 8 {
map.insert("原始数据".to_string(), MultiType::Str(data.join(" ")));
return map;
}
let mut idx = 1;
let stack_count = self.hex2int(data[idx]) as usize;
map.insert(
"燃料电池电堆个数".to_string(),
MultiType::Str(stack_count.to_string()),
);
idx += 1;
for i in 0..stack_count {
if idx + 7 > data.len() {
break;
}
let mut stack = HashMap::new();
stack.insert("序号".to_string(), MultiType::Str(data[idx].to_string()));
stack.insert(
"电压".to_string(),
MultiType::Str(
((self.hex2int(data[idx + 1]) << 8 | self.hex2int(data[idx + 2])) as f32 * 0.1)
.to_string(),
),
);
stack.insert(
"电流".to_string(),
MultiType::Str(
((self.hex2int(data[idx + 3]) << 8 | self.hex2int(data[idx + 4])) as f32 * 0.1)
.to_string(),
),
);
stack.insert(
"氢气入口压力(kPa)".to_string(),
MultiType::Str(
((self.hex2int(data[idx + 5]) << 8 | self.hex2int(data[idx + 6])) as f32 * 0.1
- 100.0)
.to_string(),
),
);
for (k, v) in stack {
map.insert(format!("电堆{}-{}", i + 1, k), v);
}
idx += 7;
}
map
}
pub fn parse_battery_min_parallel_voltage(&self, data: &[&str]) -> ParseResult {
let mut map = HashMap::new();
let sub_count = if data[1] != "FE" && data[1] != "FF" {
self.hex2int(data[1])
} else {
0
};
if sub_count > 0 {
map.insert(
"动力蓄电池包个数".to_string(),
MultiType::Int(sub_count as i64),
);
} else {
map.insert(
"动力蓄电池包个数".to_string(),
MultiType::Str(self.get_val_byte(data[1], 1.0, 0)),
);
}
let mut idx = 2;
let mut subs = Vec::new();
for _ in 0..sub_count {
if idx >= data.len() {
break;
}
let mut sub = HashMap::new();
let battery_idx = self.hex2int(data[idx]);
sub.insert(
"动力蓄电池包号".to_string(),
MultiType::Str(battery_idx.to_string()),
);
idx += 1;
let temp_probe_count_high = self.hex2int(data[idx]);
let temp_probe_count_low = self.hex2int(data[idx + 1]);
let temp_probe_count = temp_probe_count_high * 256 + temp_probe_count_low;
sub.insert(
"动力蓄电池包温度探针个数".to_string(),
MultiType::Str(temp_probe_count.to_string()),
);
idx += 2;
let mut temps = Vec::new();
for _ in 0..temp_probe_count {
if idx >= data.len() {
break;
}
let temp_i32 = self.hex2int(data[idx]) as i32 - 0x28;
temps.push(MultiType::Str(temp_i32.to_string()));
idx += 1;
}
sub.insert(
"各温度探针检测到的温度值".to_string(),
MultiType::Vec(temps),
);
subs.push(MultiType::Map(sub));
}
map.insert("动力蓄电池温度信息列表".to_string(), MultiType::Vec(subs));
ParseResult {
length: idx - 1,
data: map,
}
}
pub fn parse_battery_min_parallel_voltage_2025(&self, data: &[&str]) -> ParseResult {
let mut map = HashMap::new();
let sub_count = if data[1] != "FE" && data[1] != "FF" {
self.hex2int(data[1])
} else {
0
};
if data[1] != "FE" && data[1] != "FF" {
map.insert(
"动力蓄电池包个数".to_string(),
MultiType::Int(sub_count as i64),
);
} else {
map.insert(
"动力蓄电池包个数".to_string(),
MultiType::Str(self.get_val_byte(data[1], 1.0, 0)),
);
}
let mut idx = 2;
let mut subs = Vec::new();
for _ in 0..sub_count {
if idx >= data.len() {
break;
}
let mut sub = HashMap::new();
let battery_idx = self.get_val_byte(data[idx], 1.0, 0);
sub.insert(
"动力蓄电池包号".to_string(),
MultiType::Str(battery_idx.to_string()),
);
idx += 1;
sub.insert(
"动力蓄电池包电压".to_string(),
MultiType::Str(
self.get_float_word(data[idx], data[idx + 1], 0.1, 0, 1)
.to_string(),
),
);
idx += 2;
sub.insert(
"动力蓄电池包电流".to_string(),
MultiType::Str(
self.get_float_word(data[idx], data[idx + 1], 0.1, -0x3e8, 1)
.to_string(),
),
);
idx += 2;
let cell_count_str = self
.get_val_word(data[idx], data[idx + 1], 1.0, 0)
.to_string();
sub.insert(
"最小并联单元总数".to_string(),
MultiType::Str(cell_count_str.clone()),
);
idx += 2;
let cell_count = cell_count_str.clone().parse::<i32>().unwrap_or(0);
let mut cells = Vec::new();
for cell_index in 0..cell_count {
if idx >= data.len() {
return ParseResult {
length: idx - 1,
data: map,
};
}
let mut cell = HashMap::new();
cell.insert(
(cell_index + 1).to_string(),
MultiType::Str(self.get_float_word(data[idx], data[idx + 1], 0.001, 0, 1)),
);
cells.push(MultiType::Map(cell));
idx += 2;
}
sub.insert("本帧最小并联单元电压".to_string(), MultiType::Vec(cells));
subs.push(MultiType::Map(sub));
}
map.insert(
"动力蓄电池最小并联单元电压信息列表".to_string(),
MultiType::Vec(subs),
);
ParseResult {
length: idx - 1,
data: map,
}
}
fn parse_ota_res_rep(&self, data: &[&str]) -> HashMap<String, MultiType> {
let mut map = HashMap::new();
if data.len() < 10 {
return map;
}
let time = self.get_time(data[0], data[1], data[2], data[3], data[4], data[5]);
map.insert("时间".to_string(), MultiType::Str(time));
let upgrade_type = match data[6] {
"01" => "启动升级",
"02" => "升级结果",
"FE" => "异常",
"FF" => "无效",
_ => "未知",
};
map.insert(
"升级类型".to_string(),
MultiType::Str(upgrade_type.to_string()),
);
let response_flag = match data[7] {
"00" => "成功",
"01" => "失败",
"FE" => "异常",
"FF" => "无效",
_ => "未知",
};
map.insert(
"应答标志".to_string(),
MultiType::Str(response_flag.to_string()),
);
let fw_len = self.hex2int(data[8]);
map.insert(
"自定义固件版本长度".to_string(),
MultiType::Str(fw_len.to_string()),
);
let mut firmware = String::new();
for i in 0..fw_len as usize {
if 9 + i < data.len() {
firmware.push_str(data[9 + i]);
}
}
map.insert("固件版本号".to_string(), MultiType::Str(firmware));
let hw_len = self.hex2int(data[9 + fw_len as usize]);
map.insert(
"自定义硬件版本长度".to_string(),
MultiType::Str(hw_len.to_string()),
);
let mut hardware = String::new();
for i in 0..hw_len as usize {
if 10 + fw_len as usize + i < data.len() {
hardware.push_str(data[10 + fw_len as usize + i]);
}
}
map.insert("硬件版本号".to_string(), MultiType::Str(hardware));
if 10 + (fw_len as usize) + (hw_len as usize) < data.len() {
let error_code = format!("0x{}", data[10 + fw_len as usize + hw_len as usize]);
map.insert("升级失败错误码".to_string(), MultiType::Str(error_code));
if data[10 + fw_len as usize + hw_len as usize] == "FE" {
if 11 + fw_len as usize + hw_len as usize + 1 < data.len() {
let ext_error_code = format!(
"0x{},0x{}",
data[11 + fw_len as usize + hw_len as usize],
data[12 + fw_len as usize + hw_len as usize]
);
map.insert("扩展错误码".to_string(), MultiType::Str(ext_error_code));
}
}
}
map
}
fn parse_ecu_ota_res_rep(&self, data: &[&str]) -> HashMap<String, MultiType> {
let mut map = HashMap::new();
if data.len() < 15 {
return map;
}
let time = self.get_time(data[0], data[1], data[2], data[3], data[4], data[5]);
map.insert("时间".to_string(), MultiType::Str(time));
let ecu_id = self.hex2int(data[6]);
map.insert("ECUID".to_string(), MultiType::Str(ecu_id.to_string()));
let upgrade_result = match data[7] {
"00" => "成功",
"01" => "失败",
"FE" => "异常",
"FF" => "无效",
_ => "未知",
};
map.insert(
"升级结果".to_string(),
MultiType::Str(upgrade_result.to_string()),
);
let fw_len = self.hex2int(data[8]);
map.insert(
"自定义固件版本长度".to_string(),
MultiType::Str(fw_len.to_string()),
);
let mut firmware = String::new();
for i in 0..fw_len as usize {
if 9 + i < data.len() {
firmware.push_str(data[9 + i]);
}
}
map.insert("固件版本号".to_string(), MultiType::Str(firmware));
let hw_len = self.hex2int(data[9 + fw_len as usize]);
map.insert(
"自定义硬件版本长度".to_string(),
MultiType::Str(hw_len.to_string()),
);
let mut hardware = String::new();
for i in 0..hw_len as usize {
if 10 + fw_len as usize + i < data.len() {
hardware.push_str(data[10 + fw_len as usize + i]);
}
}
map.insert("硬件版本号".to_string(), MultiType::Str(hardware));
if 10 + (fw_len as usize) + (hw_len as usize) < data.len() {
let error_code = format!("0x{}", data[10 + fw_len as usize + hw_len as usize]);
map.insert("升级失败错误码".to_string(), MultiType::Str(error_code));
if data[10 + fw_len as usize + hw_len as usize] == "FE" {
if 11 + fw_len as usize + hw_len as usize + 1 < data.len() {
let ext_error_code = format!(
"0x{},0x{}",
data[11 + fw_len as usize + hw_len as usize],
data[12 + fw_len as usize + hw_len as usize]
);
map.insert("扩展错误码".to_string(), MultiType::Str(ext_error_code));
}
}
}
if 12 + fw_len as usize + hw_len as usize + 2 < data.len() {
let vendor_code = format!(
"{}{}{}",
data[12 + fw_len as usize + hw_len as usize],
data[13 + fw_len as usize + hw_len as usize],
data[14 + fw_len as usize + hw_len as usize]
);
map.insert("供应商代码".to_string(), MultiType::Str(vendor_code));
}
map
}
fn parse_ecu_query(&self, data: &[&str]) -> HashMap<String, MultiType> {
let mut map = HashMap::new();
if data.len() < 8 {
return map;
}
let time = self.get_time(data[0], data[1], data[2], data[3], data[4], data[5]);
map.insert("数据采集时间".to_string(), MultiType::Str(time));
let ecu_count = self.hex2int(data[6]);
map.insert("ECU数目".to_string(), MultiType::Str(ecu_count.to_string()));
let param_total = self.hex2int(data[7]);
map.insert(
"参数总数".to_string(),
MultiType::Str(param_total.to_string()),
);
let mut param_ids = Vec::new();
for i in 0..param_total as usize {
let index = 8 + i;
if index < data.len() {
param_ids.push(MultiType::Str(data[index].to_string()));
}
}
map.insert("参数ID列表".to_string(), MultiType::Vec(param_ids));
map
}
}
pub fn compare_json_values(key: &str, source: &serde_json::Value, target: &serde_json::Value) {
match (source, target) {
(serde_json::Value::Object(source_obj), serde_json::Value::Object(target_obj)) => {
for (key, source_value) in source_obj {
if let Some(target_value) = target_obj.get(key) {
compare_json_values(&key, source_value, target_value);
} else {
println!("Key '{}' exists in source but not in target", key);
}
}
for (key, _) in target_obj {
if !source_obj.contains_key(key) {
println!("Key '{}' exists in target but not in source", key);
}
}
}
(serde_json::Value::Array(source_arr), serde_json::Value::Array(target_arr)) => {
if source_arr.len() != target_arr.len() {
println!(
"Array lengths differ: source has {} elements, target has {} elements",
source_arr.len(),
target_arr.len()
);
println!("Differing elements: ");
println!("source:{:?}", &source_arr);
println!("source:{:?}", &target_arr)
}
for (_, (source_value, target_value)) in
source_arr.iter().zip(target_arr.iter()).enumerate()
{
compare_json_values(&key, source_value, target_value);
}
}
_ => {
if source != target {
println!(
"{}:,Values differ:\n source: {:?}\n target: {:?}",
&key, source, target
);
}
}
}
}