| | |
| | | import com.flightfeather.uav.socket.bean.DataUnit |
| | | import com.flightfeather.uav.socket.decoder.DataPackageDecoder |
| | | import com.flightfeather.uav.socket.decoder.DataUnitDecoder |
| | | import com.flightfeather.uav.socket.eunm.ObdCommandUnit |
| | | import com.flightfeather.uav.socket.eunm.AirCommandUnit |
| | | import java.util.* |
| | | import kotlin.text.StringBuilder |
| | | |
| | | /** |
| | | * @author riku |
| | |
| | | */ |
| | | class DataPackageDecoderImpl : DataPackageDecoder { |
| | | |
| | | companion object { |
| | | // 数据头 |
| | | const val HEAD_BYTES = 1 |
| | | // 监测参数确认指令位 |
| | | const val COMMAND_UNIT_BYTES = 1 |
| | | // 设备类型 |
| | | const val DEVICE_CODE_BYTES = 6 |
| | | // 本次监测的空气因子数量 |
| | | const val DATA_LENGTH = 1 |
| | | // 校验 |
| | | const val BCC_BYTES = 2 |
| | | } |
| | | |
| | | private val dataUnitDecoder: DataUnitDecoder = DataUnitDecoderImpl() |
| | | |
| | | // 接收到的字符串是byte转码前的,其就表示字符的ASCII码; |
| | | |
| | | override fun getHead(b: List<String>): String? { |
| | | return if (b.size >= 2) { |
| | | "${b[0]}${b[1]}" |
| | | return if (b.isNotEmpty()) { |
| | | val s = StringBuilder() |
| | | repeat(HEAD_BYTES) { |
| | | s.append(b[it]) |
| | | } |
| | | s.toString() |
| | | } else { |
| | | null |
| | | } |
| | | } |
| | | |
| | | override fun getCommandUnit(b: List<String>): Int? = if (b.size >= 3) { |
| | | b[2].toIntOrNull(16) |
| | | } else { |
| | | null |
| | | } |
| | | |
| | | override fun getVinCode(b: List<String>): String? { |
| | | if (b.size < 20) return null |
| | | |
| | | //fixme 应该是需要将b当作ASCII码,再获取转换后的字符串 |
| | | override fun getCommandUnit(b: List<String>): Int? = if (b.size >= (HEAD_BYTES + COMMAND_UNIT_BYTES)) { |
| | | val s = StringBuilder() |
| | | |
| | | for (i in 3..19) { |
| | | s.append(b[i].toIntOrNull(16)?.toChar()) |
| | | repeat(COMMAND_UNIT_BYTES) { |
| | | s.append(b[HEAD_BYTES + it]) |
| | | } |
| | | |
| | | return s.toString() |
| | | } |
| | | |
| | | override fun getSoftwareVersion(b: List<String>): Int? = if (b.size >= 21) { |
| | | b[20].toIntOrNull(16) |
| | | s.toString().toIntOrNull(16) |
| | | } else { |
| | | null |
| | | } |
| | | |
| | | override fun getEncryptionWay(b: List<String>): Int? = if (b.size >= 21) { |
| | | b[21].toIntOrNull(16) |
| | | override fun getDeviceCode(b: List<String>): String? = if (b.size >= (HEAD_BYTES + COMMAND_UNIT_BYTES + DEVICE_CODE_BYTES)) { |
| | | //2021/1/7 '0A'代表车载设备,'0B'代表无人机设备,'0C'为网格化监测 |
| | | val s = StringBuilder() |
| | | repeat(DEVICE_CODE_BYTES) { |
| | | s.append(b[HEAD_BYTES + COMMAND_UNIT_BYTES + it]) |
| | | } |
| | | s.toString() |
| | | } else { |
| | | null |
| | | } |
| | | |
| | | override fun getDataTime(b: List<String>): Date { |
| | | // FIXME: 2021/1/7 采样时间和监测因子一同放在了数据部分,此处不再做解析 |
| | | return Date() |
| | | } |
| | | |
| | | override fun getDataLength(b: List<String>): Int { |
| | | if (b.size < 24) return 0 |
| | | if (b.size <= HEAD_BYTES + COMMAND_UNIT_BYTES + DEVICE_CODE_BYTES + DATA_LENGTH) return 0 |
| | | |
| | | val hexNum = "${b[22]}${b[23]}" |
| | | val hexNum = b[HEAD_BYTES + COMMAND_UNIT_BYTES + DEVICE_CODE_BYTES] |
| | | |
| | | return hexNum.toIntOrNull(16) ?: 0 |
| | | } |
| | | |
| | | override fun getDataUnit(b: List<String>): List<DataUnit> { |
| | | if (getDataLength(b) == 0 || b.size < 26) { |
| | | if (getDataLength(b) == 0 || b.size <= HEAD_BYTES + COMMAND_UNIT_BYTES + DEVICE_CODE_BYTES + DATA_LENGTH) { |
| | | return emptyList() |
| | | } |
| | | |
| | | val unit = mutableListOf<String>() |
| | | for (i in 24..b.size - 2) { |
| | | val start = HEAD_BYTES + COMMAND_UNIT_BYTES + DEVICE_CODE_BYTES + DATA_LENGTH |
| | | for (i in start..b.size - 1 - BCC_BYTES) { |
| | | unit.add(b[i]) |
| | | } |
| | | |
| | | dataUnitDecoder.run { |
| | | return when (getCommandUnit(b)) { |
| | | ObdCommandUnit.CarRegister.value -> getCarRegisterData(unit) |
| | | ObdCommandUnit.RealTimeData.value -> getRealTimeData(unit) |
| | | ObdCommandUnit.ReplacementData.value -> getReplacementData(unit) |
| | | ObdCommandUnit.CarLogOut.value -> getCarLogOutData(unit) |
| | | ObdCommandUnit.TimeCalibration.value -> getTimeCalibrationData(unit) |
| | | AirCommandUnit.Confirm.value -> getAirConfirmData(unit, getDeviceCode(b)) |
| | | AirCommandUnit.AirData.value -> getAirData(unit, getDeviceCode(b)) |
| | | else -> emptyList() |
| | | } |
| | | } |
| | | } |
| | | |
| | | override fun getCheckCode(b: List<String>): Int? { |
| | | return if (b.isNotEmpty()) { |
| | | b[b.size - 1].toIntOrNull(16) |
| | | return if (b.size >= HEAD_BYTES + COMMAND_UNIT_BYTES + DEVICE_CODE_BYTES + BCC_BYTES) { |
| | | val hexNum = "${b[b.size - 2]}${b[b.size - 1]}" |
| | | |
| | | hexNum.toIntOrNull(16) |
| | | } else { |
| | | null |
| | | } |