package com.flightfeather.obd.socket.decoder.impl
|
|
import com.flightfeather.obd.socket.bean.EngineDataFlow
|
import com.flightfeather.obd.socket.bean.ObdData
|
import com.flightfeather.obd.socket.bean.SupplementDataFlow
|
import com.flightfeather.obd.socket.decoder.RealTimeDataDecoder
|
import com.flightfeather.obd.socket.eunm.ObdDataType
|
import org.springframework.stereotype.Component
|
import java.util.*
|
|
/**
|
* @author riku
|
* Date: 2019/9/15
|
*/
|
class RealTimeDataDecoderImpl : RealTimeDataDecoder {
|
override fun getObdData(time: Date?, serialNum: Int, b: List<String>): ObdData? {
|
val dataList = mutableListOf<String>().apply { addAll(b) }
|
if (b.isNotEmpty()) {
|
//去除 信息类型标志
|
dataList.removeAt(0)
|
}
|
if (dataList.size >= 96) {
|
val vin = StringBuilder()
|
for (i in 6..22) {
|
vin.append(dataList[i].toIntOrNull(16)?.toChar())
|
}
|
val softwareCode = StringBuilder()
|
for (i in 23..40) {
|
softwareCode.append(dataList[i].toIntOrNull(16)?.toChar())
|
}
|
val cvn = StringBuilder()
|
for (i in 41..58) {
|
cvn.append(dataList[i].toIntOrNull(16)?.toChar())
|
}
|
val IUPR = StringBuilder()
|
for (i in 59..94) {
|
//todo 2019.9.15 因暂不清楚格式与含义,直接保存
|
IUPR.append(dataList[i])
|
}
|
var faultCodeNum = dataList[95].toIntOrNull() ?: 0
|
val faultCode = StringBuilder()
|
if (faultCodeNum < 0 || faultCodeNum > 253) {
|
faultCodeNum = 254//代表无效
|
} else {
|
for (i in 96..(95 + 4 * faultCodeNum)) {
|
faultCode.append(dataList[i])
|
}
|
}
|
|
return ObdData(time, serialNum).apply {
|
obdProtocol = dataList[0].toIntOrNull(16)
|
obdMil = dataList[1].toIntOrNull(16)
|
diagnosisSupportStatus = "${dataList[2]}${dataList[3]}".toIntOrNull(16)?.toString(2)
|
diagnosisReadyStatus = "${dataList[4]}${dataList[5]}".toIntOrNull(16)?.toString(2)
|
obdVin = vin.toString()
|
obdSoftwareCode = softwareCode.toString()
|
obdCvn = cvn.toString()
|
this.IUPR = IUPR.toString()
|
obdFaultCodeNum = faultCodeNum
|
obdFaultCode = faultCode.toString()
|
}
|
} else {
|
return null
|
}
|
}
|
|
override fun getEngineDataFlow(time: Date?, serialNum: Int, b: List<String>): EngineDataFlow? {
|
val dataList = mutableListOf<String>().apply { addAll(b) }
|
if (b.isNotEmpty()) {
|
//去除 信息类型标志
|
dataList.removeAt(0)
|
}
|
|
return if (dataList.size >= 37) {
|
EngineDataFlow(time, serialNum).apply {
|
obdSpeed = "${dataList[0]}${dataList[1]}".toIntOrNull(16)?.toDouble()?.times((1 / 256).toDouble())
|
obdAirPressure = dataList[2].toIntOrNull(16)?.toDouble()?.times(0.5)
|
obdEngineTorque = dataList[3].toIntOrNull(16)?.minus(125)?.toDouble()?.div(100)
|
obdFrictionTorque = dataList[4].toIntOrNull(16)?.minus(125)?.toDouble()?.div(100)
|
obdEngineRpm = "${dataList[5]}${dataList[6]}".toIntOrNull(16)?.toDouble()?.times(0.125)
|
obdEngineFuelFlow = "${dataList[7]}${dataList[8]}".toIntOrNull(16)?.toDouble()?.times(0.05)
|
obdScrUpstreamNo = "${dataList[9]}${dataList[10]}".toIntOrNull(16)?.minus(200)?.toDouble()?.times(0.05)
|
obdScrDownstreamNo = "${dataList[11]}${dataList[12]}".toIntOrNull(16)?.minus(200)?.toDouble()?.times(0.05)
|
obdRemainReactant = dataList[13].toIntOrNull(16)?.toDouble()?.times(0.4)?.div(100)
|
obdAirInput = "${dataList[14]}${dataList[15]}".toIntOrNull(16)?.toDouble()?.times(0.05)
|
obdScrInputTemp = "${dataList[16]}${dataList[17]}".toIntOrNull(16)?.minus(273)?.toDouble()?.times(0.03125)
|
obdScrOutputTemp = "${dataList[18]}${dataList[19]}".toIntOrNull(16)?.minus(273)?.toDouble()?.times(0.03125)
|
obdDpf = "${dataList[20]}${dataList[21]}".toIntOrNull(16)?.toDouble()?.times(0.1)
|
obdEngineCoolantTemp = dataList[22].toIntOrNull(16)?.minus(40)?.toDouble()
|
obdFuelLevel = dataList[23].toIntOrNull(16)?.toDouble()?.times(0.4)
|
obdLocationStatus = dataList[24].toIntOrNull(16)
|
obdLong = "${dataList[25]}${dataList[26]}${dataList[27]}${dataList[28]}".toIntOrNull(16)?.toDouble()?.times(0.000001)
|
obdLat = "${dataList[29]}${dataList[30]}${dataList[31]}${dataList[32]}".toIntOrNull(16)?.toDouble()?.times(0.000001)
|
obdTotalMileage = "${dataList[33]}${dataList[34]}${dataList[35]}${dataList[36]}".toIntOrNull(16)?.toDouble()?.times(0.1)
|
}
|
} else {
|
null
|
}
|
}
|
|
override fun getSupplementDataFlow(time: Date?, serialNum: Int, b: List<String>): SupplementDataFlow? {
|
val dataList = mutableListOf<String>().apply { addAll(b) }
|
if (b.isNotEmpty()) {
|
//去除 信息类型标志
|
dataList.removeAt(0)
|
}
|
|
return if (dataList.size >= 17) {
|
SupplementDataFlow(time, serialNum).apply {
|
obdEngineTorqueMode = dataList[0].toIntOrNull(16)
|
obdAcceleratorPedal = dataList[1].toIntOrNull(16)?.toDouble()?.times(0.4)?.div(100)
|
obdTotalOilConsumption = "${dataList[2]}${dataList[3]}${dataList[4]}${dataList[5]}".toIntOrNull(16)?.toDouble()?.times(0.5)
|
obdUreaBoxTemp = dataList[6].toIntOrNull(16)?.toDouble()?.minus(40)
|
obdUreaVolume = "${dataList[7]}${dataList[8]}${dataList[9]}${dataList[10]}".toIntOrNull(16)?.toDouble()?.times(0.01)
|
obdTotalUreaConsume = "${dataList[11]}${dataList[12]}${dataList[13]}${dataList[14]}".toIntOrNull(16)?.toDouble()
|
obdDpfTemp = "${dataList[15]}${dataList[16]}".toIntOrNull(16)?.minus(273)?.toDouble()?.times(0.03125)
|
}
|
} else {
|
null
|
}
|
}
|
|
override fun getDataListByDataType(list: List<String>): MutableList<String> {
|
if (list.isEmpty()) return mutableListOf()
|
|
//fixme 2019.9.16 不管第一位的信息类型标志是否正确,至少返回一个值,此方法在信息体结构没有严格按照标准,
|
//fixme 即在后一个信息类型标志和前一个信息体之间有无效字符时,能够将其忽略,但不确定这种处理方式是否正确和必要
|
val resultList = mutableListOf<String>().apply {
|
add(list[0])
|
}
|
|
when (list[0].toIntOrNull(16)) {
|
ObdDataType.ObdData.value -> {
|
|
//从起始字节 1 开始,固定有97个字节的数据
|
for (i in 1..96) {
|
resultList.add(list[i])
|
}
|
|
val faultCodeNum = list[96].toIntOrNull() ?: 0//故障码总数
|
//根据故障码总数,每个故障码4个字节,得到故障码总字节数
|
if (faultCodeNum in 0..253) {
|
for (i in 97..(96 + faultCodeNum * 4)) {
|
resultList.add(list[i])
|
}
|
}
|
}
|
ObdDataType.EngineDataFlow.value -> {
|
|
//从起始字节 1 开始,固定有37个字节的数据
|
for (i in 1..37) {
|
resultList.add(list[i])
|
}
|
}
|
ObdDataType.SupplementDataFlow.value -> {
|
|
//从起始字节 1 开始,固定有17个字节的数据
|
for (i in 1..17) {
|
resultList.add(list[i])
|
}
|
}
|
}
|
|
return resultList
|
}
|
|
}
|