From 4d44ed185203088052b10a8d1e3526fcbbc88331 Mon Sep 17 00:00:00 2001 From: riku <risaku@163.com> Date: 星期日, 15 九月 2019 18:42:31 +0800 Subject: [PATCH] obd 数据解码逻辑完成 --- src/test/kotlin/com/flightfeather/obd/Test.kt | 88 ++++ src/main/kotlin/com/flightfeather/obd/lightshare/bean/ObdDataVo.kt | 2 src/main/kotlin/com/flightfeather/obd/common/utils/FileUtil.kt | 103 ++++ src/main/kotlin/com/flightfeather/obd/socket/decoder/RealTimeDataDecoder.kt | 26 + src/main/kotlin/com/flightfeather/obd/socket/eunm/ObdCommandUnit.kt | 14 pom.xml | 13 src/main/kotlin/com/flightfeather/obd/repository/impl/ObdDataDaoImpl.kt | 77 +++ src/main/kotlin/com/flightfeather/obd/socket/bean/EngineDataFlow.kt | 33 + src/main/kotlin/com/flightfeather/obd/common/packgeinfo | 0 src/main/kotlin/com/flightfeather/obd/socket/decoder/impl/DataUnitDecoderImpl.kt | 123 +++++ src/main/kotlin/com/flightfeather/obd/socket/bean/CarLogOutData.kt | 14 src/main/kotlin/com/flightfeather/obd/socket/eunm/ObdDataType.kt | 19 src/main/kotlin/com/flightfeather/obd/socket/bean/ObdPackageData.kt | 16 src/main/kotlin/com/flightfeather/obd/socket/decoder/DataPackageDecoder.kt | 42 ++ src/main/kotlin/com/flightfeather/obd/socket/bean/TimeCalibrationData.kt | 8 src/main/kotlin/com/flightfeather/obd/socket/SocketServerClient.kt | 14 src/main/kotlin/com/flightfeather/obd/socket/decoder/impl/DataPackageDecoderImpl.kt | 98 ++++ src/main/kotlin/com/flightfeather/obd/socket/bean/DataUnit.kt | 8 src/main/kotlin/com/flightfeather/obd/socket/bean/SupplementDataFlow.kt | 57 ++ src/main/kotlin/com/flightfeather/obd/repository/ObdDataRepository.kt | 4 src/main/kotlin/com/flightfeather/obd/socket/bean/ReplacementData.kt | 9 src/main/resources/log4j2.xml | 67 +++ src/main/kotlin/com/flightfeather/obd/socket/decoder/VehicleDataDecoder.kt | 35 + src/main/kotlin/com/flightfeather/obd/socket/decoder/DataUnitDecoder.kt | 36 + src/main/kotlin/com/flightfeather/obd/socket/decoder/impl/RealTimeDataDecoderImpl.kt | 163 +++++++ src/main/kotlin/com/flightfeather/obd/socket/bean/RealTimeData.kt | 13 src/main/kotlin/com/flightfeather/obd/socket/bean/CarRegisterData.kt | 20 src/test/kotlin/com/flightfeather/obd/ObdApplicationTests.kt | 11 src/main/kotlin/com/flightfeather/obd/socket/MessageManager.kt | 43 + src/main/kotlin/com/flightfeather/obd/socket/bean/ObdData.kt | 25 + src/main/kotlin/com/flightfeather/obd/socket/ServerHandler.kt | 33 + src/main/resources/application.yml | 1 32 files changed, 1,188 insertions(+), 27 deletions(-) diff --git a/pom.xml b/pom.xml index ed3e0cc..5ee699e 100644 --- a/pom.xml +++ b/pom.xml @@ -27,6 +27,13 @@ <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> + <exclusions> + <!-- 鍘婚櫎鏃og渚濊禆 --> + <exclusion> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-logging</artifactId> + </exclusion> + </exclusions> </dependency> <dependency> <groupId>com.fasterxml.jackson.module</groupId> @@ -103,6 +110,12 @@ <version>1.2.12</version> </dependency> + <!--澧炲姞log4j2渚濊禆鈫�--> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-log4j2</artifactId> + </dependency> + </dependencies> <build> diff --git a/src/main/kotlin/com/flightfeather/obd/common/packgeinfo b/src/main/kotlin/com/flightfeather/obd/common/packgeinfo new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/main/kotlin/com/flightfeather/obd/common/packgeinfo diff --git a/src/main/kotlin/com/flightfeather/obd/common/utils/FileUtil.kt b/src/main/kotlin/com/flightfeather/obd/common/utils/FileUtil.kt new file mode 100644 index 0000000..7dea200 --- /dev/null +++ b/src/main/kotlin/com/flightfeather/obd/common/utils/FileUtil.kt @@ -0,0 +1,103 @@ +package com.flightfeather.obd.common.utils + +import java.io.BufferedWriter +import java.io.File +import java.io.FileWriter +import java.text.SimpleDateFormat +import java.util.* + +/** + * @author riku + * Date: 2019/9/11 + */ +class FileUtil { + + private var file: File + private var basePath:String = "${File.separator}ObdData${File.separator}" + private var closeThread: Thread? = null + private var fw: FileWriter? = null + private var bw: BufferedWriter? = null + + init { + val fileName = "data-${SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(Date())}.txt" + val path = "$basePath$fileName" + file = File(path) + } + + companion object{ + var instance: FileUtil? = null + get() { + if (field == null) { + field = FileUtil() + } + return field + } + } + + fun saveObdData(str: String) { + //妫�鏌ユ枃妗f槸鍚﹀瓨鍦� + if (!file.exists()) { + file.parentFile.mkdirs() + println("----鍒涘缓鏂囦欢澶癸細${file.parentFile.absolutePath}") + file.createNewFile() + println("----鍒涘缓鏂囦欢锛�${file.absolutePath}") + } + //鏂囦欢鏈�澶�512Kb,瓒呰繃鍚庢柊寤烘枃妗� + if (file.length() + str.toByteArray().size > 512 * 1024) { + val fileName = "data-${SimpleDateFormat("yyyy-MM-dd-hh-mm-ss").format(Date())}.txt" + val path = "$basePath$fileName" + file = File(path) + file.createNewFile() + + //鍏抽棴鍘熸湁杈撳嚭娴� + bw?.run { + flush() + close() + } + fw?.run { + flush() + close() + } + //鏂板缓杈撳嚭娴� + fw = FileWriter(file, true) + bw = BufferedWriter(fw) + } + //绗竴娆″啓鏂囨。鏃跺垵濮嬪寲杈撳嚭娴� + if (bw == null || fw == null) { + fw = FileWriter(file, true) + bw = BufferedWriter(fw) + } + + bw?.run { + write(str) + newLine() + flush() + } + + readyToShutDownStream(bw, fw) + println("----鍐欏叆瀹屾垚") + + } + + private fun readyToShutDownStream(bw: BufferedWriter?, fw:FileWriter?) { + //缁堢涓婁竴娆$殑璁℃椂绾跨▼ + closeThread?.interrupt() + closeThread = Thread(Runnable { + //2鍒嗛挓娌℃湁鏂扮殑鏁版嵁鍐欏叆灏卞叧闂緭鍑烘祦 + try { + Thread.sleep(20 * 1000) + } catch (e: Throwable) { + } + bw?.run { + close() + } + this.bw = null + fw?.run { + close() + } + this.fw = null + }).also { + it.start() + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/obd/lightshare/bean/ObdDataVo.kt b/src/main/kotlin/com/flightfeather/obd/lightshare/bean/ObdDataVo.kt index 35b228b..8f680b5 100644 --- a/src/main/kotlin/com/flightfeather/obd/lightshare/bean/ObdDataVo.kt +++ b/src/main/kotlin/com/flightfeather/obd/lightshare/bean/ObdDataVo.kt @@ -22,7 +22,7 @@ var obdEngineTorque: Double? = null var obdFrictionTorque: Double? = null var obdEngineRpm: Int? = null - var obdStartFuelFlow: Double? = null + var obdEngineFuelFlow: Double? = null var obdScrUpstreamNo: Double? = null var obdScrDownstreamNo: Double? = null var obdRemainReactant: Double? = null diff --git a/src/main/kotlin/com/flightfeather/obd/repository/ObdDataRepository.kt b/src/main/kotlin/com/flightfeather/obd/repository/ObdDataRepository.kt index 04bea7a..97e678d 100644 --- a/src/main/kotlin/com/flightfeather/obd/repository/ObdDataRepository.kt +++ b/src/main/kotlin/com/flightfeather/obd/repository/ObdDataRepository.kt @@ -3,6 +3,7 @@ import com.flightfeather.obd.domain.entity.ObdData import com.flightfeather.obd.domain.mapper.ObdDataMapper import com.flightfeather.obd.lightshare.bean.ObdDataVo +import com.flightfeather.obd.socket.bean.ObdPackageData import org.springframework.beans.BeanUtils import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Component @@ -23,4 +24,7 @@ * 閫氳繃姹借溅vin鐮佽幏鍙栨渶鏂版暟鎹� */ fun getDataByVinCode(vinCode: String, pageNum: Int?, pageSize: Int?): MutableList<ObdDataVo> + + fun saveObdData(packageData: ObdPackageData):Boolean + } \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/obd/repository/impl/ObdDataDaoImpl.kt b/src/main/kotlin/com/flightfeather/obd/repository/impl/ObdDataDaoImpl.kt index 4b49491..4abd7af 100644 --- a/src/main/kotlin/com/flightfeather/obd/repository/impl/ObdDataDaoImpl.kt +++ b/src/main/kotlin/com/flightfeather/obd/repository/impl/ObdDataDaoImpl.kt @@ -4,6 +4,10 @@ import com.flightfeather.obd.domain.mapper.ObdDataMapper import com.flightfeather.obd.lightshare.bean.ObdDataVo import com.flightfeather.obd.repository.ObdDataRepository +import com.flightfeather.obd.socket.bean.EngineDataFlow +import com.flightfeather.obd.socket.bean.ObdPackageData +import com.flightfeather.obd.socket.bean.SupplementDataFlow +import com.flightfeather.obd.socket.eunm.ObdCommandUnit import com.github.pagehelper.PageHelper import org.springframework.beans.BeanUtils import org.springframework.stereotype.Repository @@ -43,4 +47,77 @@ return resultList } + + override fun saveObdData(packageData: ObdPackageData): Boolean { + val obdData = ObdData().apply { + obdVin = packageData.vinCode + } + when (packageData.commandUnit) { + ObdCommandUnit.CarRegister.value -> { + + } + ObdCommandUnit.RealTimeData.value, + ObdCommandUnit.ReplacementData.value -> { + packageData.dataUnit.forEach { + when (it) { + is com.flightfeather.obd.socket.bean.ObdData -> { + obdData.apply { + obdTime = it.time + obdProtocol = it.obdProtocol + obdMil = it.obdMil + obdIdCode = it.obdSoftwareCode + obdVerificationCode = it.obdCvn + obdFaultCodeNum = it.obdFaultCodeNum + obdFaultCode = it.obdFaultCode + } + } + is EngineDataFlow -> { + obdData.apply { + obdLng = it.obdLong + obdLat = it.obdLat + obdSpeed = it.obdSpeed?.toInt() + obdAirPressure = it.obdAirPressure + obdEngineTorque = it.obdEngineTorque + obdFrictionTorque = it.obdFrictionTorque + obdEngineRpm = it.obdEngineRpm?.toInt() + obdStartFuelFlow = it.obdEngineFuelFlow + obdScrUpstreamNo = it.obdScrUpstreamNo + obdScrDownstreamNo = it.obdScrDownstreamNo + obdRemainReactant = it.obdRemainReactant + obdAirInput = it.obdAirInput + obdScrInputTemp = it.obdScrInputTemp + obdScrOutputTemp = it.obdScrOutputTemp + obdDpf = it.obdDpf + obdEngineCoolantTemp = it.obdEngineCoolantTemp + obdFuelLevel = it.obdFuelLevel + obdLocationStatus = it.obdLocationStatus + obdTotalMileage = it.obdTotalMileage + } + } + is SupplementDataFlow -> { + obdData.apply { + obdEngineTorqueMode = it.obdEngineTorqueMode?.toString() + obdAcceleratorPedal = it.obdAcceleratorPedal + obdTotalOilConsumption = it.obdTotalOilConsumption + obdUreaBoxTemp = it.obdUreaBoxTemp + obdUreaVolume = it.obdUreaVolume?.toInt() + obdTotalUreaConsume = it.obdTotalUreaConsume + obdDpfTemp = it.obdDpfTemp +// obdFirmwareVersion = + } + } + } + } + + } + ObdCommandUnit.CarLogOut.value -> { + + } + ObdCommandUnit.TimeCalibration.value -> { + + } + } + + return obdDataMapper.insert(obdData) == 1 + } } \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/obd/socket/MessageManager.kt b/src/main/kotlin/com/flightfeather/obd/socket/MessageManager.kt index b709839..6f1a280 100644 --- a/src/main/kotlin/com/flightfeather/obd/socket/MessageManager.kt +++ b/src/main/kotlin/com/flightfeather/obd/socket/MessageManager.kt @@ -1,12 +1,15 @@ package com.flightfeather.obd.socket +import com.flightfeather.obd.common.utils.FileUtil import com.flightfeather.obd.lightshare.bean.BaseJson import com.flightfeather.obd.lightshare.bean.ObdDataVo import com.flightfeather.obd.repository.ObdDataRepository +import com.flightfeather.obd.socket.decoder.VehicleDataDecoder import com.google.gson.Gson import io.netty.channel.ChannelHandlerContext import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Component +import org.springframework.util.FileSystemUtils import javax.annotation.PostConstruct import javax.annotation.Resource @@ -26,24 +29,38 @@ @Autowired lateinit var obdDataRepository: ObdDataRepository + val vehicleDataDecoder = VehicleDataDecoder() + @PostConstruct fun init() { instance = this instance.obdDataRepository = this.obdDataRepository } - fun dealMsg(msg: String, ctx: ChannelHandlerContext?) { - try { - val baseJson = Gson().fromJson<BaseJson>(msg, BaseJson::class.java) - when (baseJson.cmdCode) { - 2001 -> { - val data = Gson().fromJson(msg, ObdDataVo::class.java) - DeviceSession.saveDevice(data.obdVin, ctx) - instance.obdDataRepository.saveObdData(data) - } - } - } catch (e: Throwable) { -// println("------鏀跺埌鏍煎紡閿欒鐨勬暟鎹細$msg") - } + fun dealStringMsg(msg: String, ctx: ChannelHandlerContext?) { +// try { +// val baseJson = Gson().fromJson<BaseJson>(msg, BaseJson::class.java) +// when (baseJson.cmdCode) { +// 2001 -> { +// val data = Gson().fromJson(msg, ObdDataVo::class.java) +// DeviceSession.saveDevice(data.obdVin, ctx) +// instance.obdDataRepository.saveObdData(data) +// } +// } +// } catch (e: Throwable) { +// } + + saveToTxt(msg) + val packageData = vehicleDataDecoder.decode(msg) + } + + fun dealByteArrayMsg(msg: ByteArray, ctx: ChannelHandlerContext?) { + val b = ByteArray(20) {19} + println(b) + } + + fun saveToTxt(msg: String) { + val data = "data=> $msg" + FileUtil.instance?.saveObdData(data) } } \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/obd/socket/ServerHandler.kt b/src/main/kotlin/com/flightfeather/obd/socket/ServerHandler.kt index a71b02e..d904bca 100644 --- a/src/main/kotlin/com/flightfeather/obd/socket/ServerHandler.kt +++ b/src/main/kotlin/com/flightfeather/obd/socket/ServerHandler.kt @@ -3,6 +3,9 @@ import io.netty.channel.ChannelHandlerContext import io.netty.channel.ChannelInboundHandlerAdapter import io.netty.util.AttributeKey +import java.lang.StringBuilder +import java.text.SimpleDateFormat +import java.util.* class ServerHandler : ChannelInboundHandlerAdapter() { @@ -11,6 +14,7 @@ override fun channelRegistered(ctx: ChannelHandlerContext?) { super.channelRegistered(ctx) +// ctx?.fireChannelActive() } override fun channelActive(ctx: ChannelHandlerContext?) { @@ -19,16 +23,27 @@ override fun channelRead(ctx: ChannelHandlerContext?, msg: Any?) { super.channelRead(ctx, msg) - println("------鏀跺埌鐨勫師濮嬫暟鎹細[ip:${ctx?.channel()?.remoteAddress()}]\r\n$msg") - if (msg is String) { - MessageManager().dealMsg(msg, ctx) - } -// val attribute = ctx?.channel()?.attr(attributeKey)?.apply { -// if (get() == null) { -// set(data.obdVin) -// } -// } + val sb = StringBuilder() + + if (msg is ByteArray) { + println("------鏀跺埌鐨勫師濮嬫暟鎹細[ip:${ctx?.channel()?.remoteAddress()}] ${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())}") + msg.forEach { + var a = 0 + a = if (it < 0) { + it + 256 + } else { + it.toInt() + } + print("${a.toString(16)} ") + sb.append(a.toString(16)).append(" ") + } + sb.deleteCharAt(sb.length - 1) + } + val str = sb.toString() + if (str.isNotEmpty()) { + MessageManager().dealStringMsg(str, ctx) + } } diff --git a/src/main/kotlin/com/flightfeather/obd/socket/SocketServerClient.kt b/src/main/kotlin/com/flightfeather/obd/socket/SocketServerClient.kt index 4c1f489..991a4e7 100644 --- a/src/main/kotlin/com/flightfeather/obd/socket/SocketServerClient.kt +++ b/src/main/kotlin/com/flightfeather/obd/socket/SocketServerClient.kt @@ -4,10 +4,12 @@ import io.netty.channel.ChannelInitializer import io.netty.channel.ChannelOption import io.netty.channel.nio.NioEventLoopGroup -import io.netty.channel.socket.SocketChannel import io.netty.channel.socket.nio.NioServerSocketChannel import io.netty.channel.socket.nio.NioSocketChannel +import io.netty.handler.codec.bytes.ByteArrayDecoder +import io.netty.handler.codec.bytes.ByteArrayEncoder import io.netty.handler.codec.string.StringDecoder +import io.netty.handler.codec.string.StringEncoder /** * socket闀胯繛鎺ユ湇鍔$ @@ -34,15 +36,19 @@ return ServerBootstrap() .group(bossGroup, workerGroup) .channel(NioServerSocketChannel::class.java) + .option(ChannelOption.SO_BACKLOG, 128) + .childOption(ChannelOption.SO_KEEPALIVE, true) + .childOption(ChannelOption.TCP_NODELAY, true) .childHandler(object : ChannelInitializer<NioSocketChannel>() { override fun initChannel(p0: NioSocketChannel?) { p0?.pipeline() - ?.addLast(StringDecoder()) +// ?.addLast("decoder", StringDecoder()) +// ?.addLast("encoder", StringEncoder()) + ?.addLast(ByteArrayDecoder()) + ?.addLast(ByteArrayEncoder()) ?.addLast(ServerHandler()) } }) - .option(ChannelOption.SO_BACKLOG, 128) - .childOption(ChannelOption.SO_KEEPALIVE, true) } catch (e: Throwable) { e.printStackTrace() } diff --git a/src/main/kotlin/com/flightfeather/obd/socket/bean/CarLogOutData.kt b/src/main/kotlin/com/flightfeather/obd/socket/bean/CarLogOutData.kt new file mode 100644 index 0000000..954fdfd --- /dev/null +++ b/src/main/kotlin/com/flightfeather/obd/socket/bean/CarLogOutData.kt @@ -0,0 +1,14 @@ +package com.flightfeather.obd.socket.bean + +import java.util.* + +/** + * @author riku + * Date: 2019/9/12 + * 杞﹁締鐧诲嚭淇℃伅 + * + */ +class CarLogOutData( + var time: Date? = null, + var serialNum: Int? = null +): DataUnit() \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/obd/socket/bean/CarRegisterData.kt b/src/main/kotlin/com/flightfeather/obd/socket/bean/CarRegisterData.kt new file mode 100644 index 0000000..e06beae --- /dev/null +++ b/src/main/kotlin/com/flightfeather/obd/socket/bean/CarRegisterData.kt @@ -0,0 +1,20 @@ +package com.flightfeather.obd.socket.bean + +import java.util.* + +/** + * @author riku + * Date: 2019/9/12 + * + * 杞﹁締鐧诲叆鏁版嵁鏍煎紡 + * + * 璧峰瀛楄妭 鍐呭 鎻忚堪 + * 0 鏁版嵁閲囬泦鏃堕棿 鏃堕棿瀹氫箟瑙� 6.4.4 + * 6 鐧诲叆娴佹按鍙� 杞﹁浇缁堢姣忕櫥鍏ヤ竴娆★紝鐧诲叆娴佹按鍙疯嚜鍔ㄥ姞 1锛屼粠 1寮�濮嬪惊鐜疮鍔狅紝鏈�澶у�间负 65531锛屽惊鐜懆鏈熶负澶┿�� + * 10 SIM 鍗″彿 SIM 鍗� ICCID 鍙凤紙ICCID 搴斾负缁堢浠� SIM 鍗¤幏鍙栫殑鍊硷紝涓嶅簲浜轰负濉啓鎴栦慨鏀癸級銆� + */ +class CarRegisterData( + var time: Date? = null, + var serialNum: Int? = null, + var SIMCode: String? = null +): DataUnit() \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/obd/socket/bean/DataUnit.kt b/src/main/kotlin/com/flightfeather/obd/socket/bean/DataUnit.kt new file mode 100644 index 0000000..b63c8d1 --- /dev/null +++ b/src/main/kotlin/com/flightfeather/obd/socket/bean/DataUnit.kt @@ -0,0 +1,8 @@ +package com.flightfeather.obd.socket.bean + +/** + * @author riku + * Date: 2019/9/12 + */ +open class DataUnit { +} \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/obd/socket/bean/EngineDataFlow.kt b/src/main/kotlin/com/flightfeather/obd/socket/bean/EngineDataFlow.kt new file mode 100644 index 0000000..12ff10c --- /dev/null +++ b/src/main/kotlin/com/flightfeather/obd/socket/bean/EngineDataFlow.kt @@ -0,0 +1,33 @@ +package com.flightfeather.obd.socket.bean + +import java.util.* + +/** + * @author riku + * Date: 2019/9/15 + * 鍙戝姩鏈烘暟鎹祦 + */ +class EngineDataFlow( + time: Date?, + serialNum: Int? +) : RealTimeData(time, serialNum) { + var obdSpeed: Double? = null + var obdAirPressure: Double? = null + var obdEngineTorque: Double? = null + var obdFrictionTorque: Double? = null + var obdEngineRpm: Double? = null + var obdEngineFuelFlow: Double? = null + var obdScrUpstreamNo: Double? = null + var obdScrDownstreamNo: Double? = null + var obdRemainReactant: Double? = null + var obdAirInput: Double? = null + var obdScrInputTemp: Double? = null + var obdScrOutputTemp: Double? = null + var obdDpf: Double? = null + var obdEngineCoolantTemp: Double? = null + var obdFuelLevel: Double? = null + var obdLocationStatus: Int? = null + var obdLong: Double? = null + var obdLat: Double? = null + var obdTotalMileage: Double? = null +} \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/obd/socket/bean/ObdData.kt b/src/main/kotlin/com/flightfeather/obd/socket/bean/ObdData.kt new file mode 100644 index 0000000..817accf --- /dev/null +++ b/src/main/kotlin/com/flightfeather/obd/socket/bean/ObdData.kt @@ -0,0 +1,25 @@ +package com.flightfeather.obd.socket.bean + +import com.flightfeather.obd.socket.bean.* +import java.util.* + +/** + * @author riku + * Date: 2019/9/15 + * 瀹炴椂淇℃伅[RealTimeData] 涓殑obd鏁版嵁 + */ +class ObdData( + time: Date?, + serialNum: Int? +) : RealTimeData(time, serialNum) { + var obdProtocol: Int? = null + var obdMil: Int? = null + var diagnosisSupportStatus: String? = null//璇婃柇鏀寔鐘舵�� + var diagnosisReadyStatus: String? = null//璇婃柇灏辩华鐘舵�� + var obdVin: String? = null + var obdSoftwareCode: String? = null//杞欢鏍囧畾璇嗗埆鍙� + var obdCvn: String? = null//鏍囧畾楠岃瘉鐮� + var IUPR:String?=null//瀹氫箟鍙傝�� SAE J 1979-DA 琛� G11 + var obdFaultCodeNum: Int? = null//鏁呴殰鐮佹�绘暟: 鏈夋晥鍊艰寖鍥达細0~253锛屸��0xFE鈥濊〃绀烘棤鏁堛�� + var obdFaultCode: String? = null//鏁呴殰鐮佷俊鎭垪琛�: 姣忎釜鏁呴殰鐮佷负鍥涘瓧鑺傦紝鍙寜鏁呴殰瀹為檯椤哄簭杩涜鎺掑簭 +} \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/obd/socket/bean/ObdPackageData.kt b/src/main/kotlin/com/flightfeather/obd/socket/bean/ObdPackageData.kt new file mode 100644 index 0000000..838a048 --- /dev/null +++ b/src/main/kotlin/com/flightfeather/obd/socket/bean/ObdPackageData.kt @@ -0,0 +1,16 @@ +package com.flightfeather.obd.socket.bean + +/** + * @author riku + * Date: 2019/9/12 + */ +data class ObdPackageData constructor( + var head: String? = null, + var commandUnit: Int? = null, + var vinCode: String? = null, + var softwareVersion: Int? = null, + var encryptionWay: Int? = null, + var dataLength: Int? = null, + var dataUnit: List<DataUnit>, + var checkCode: Int? = null +) \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/obd/socket/bean/RealTimeData.kt b/src/main/kotlin/com/flightfeather/obd/socket/bean/RealTimeData.kt new file mode 100644 index 0000000..619c311 --- /dev/null +++ b/src/main/kotlin/com/flightfeather/obd/socket/bean/RealTimeData.kt @@ -0,0 +1,13 @@ +package com.flightfeather.obd.socket.bean + +import java.util.* + +/** + * @author riku + * Date: 2019/9/12 + * + */ +open class RealTimeData( + var time: Date? = null, + var serialNum: Int? = null +) : ReplacementData() \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/obd/socket/bean/ReplacementData.kt b/src/main/kotlin/com/flightfeather/obd/socket/bean/ReplacementData.kt new file mode 100644 index 0000000..e5f8b6b --- /dev/null +++ b/src/main/kotlin/com/flightfeather/obd/socket/bean/ReplacementData.kt @@ -0,0 +1,9 @@ +package com.flightfeather.obd.socket.bean + +/** + * @author riku + * Date: 2019/9/12 + * 琛ュ彂淇℃伅涓庡疄鏃朵俊鎭唴瀹逛竴鑷� + */ +open class ReplacementData : DataUnit() { +} \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/obd/socket/bean/SupplementDataFlow.kt b/src/main/kotlin/com/flightfeather/obd/socket/bean/SupplementDataFlow.kt new file mode 100644 index 0000000..b5bf0f1 --- /dev/null +++ b/src/main/kotlin/com/flightfeather/obd/socket/bean/SupplementDataFlow.kt @@ -0,0 +1,57 @@ +package com.flightfeather.obd.socket.bean + +import java.util.* + +/** + * @author riku + * Date: 2019/9/15 + * 琛ュ厖鏁版嵁娴� + * + * 璧峰瀛楄妭 鏁版嵁椤� 鏁版嵁绫诲瀷 鍗曚綅 鎻忚堪鍙婅姹� + * 0 鍙戝姩鏈烘壄鐭╂ā寮� BYTE 0锛氳秴閫熷け鏁� + * 1锛氳浆閫熸帶鍒� + * 2锛氭壄鐭╂帶鍒� + * 3锛氳浆閫�/鎵煩鎺у埗 + * 1 娌归棬韪忔澘 BYTE % 鏁版嵁闀垮害锛�1bytes + * 绮惧害锛�0.4%/bit + * 鍋忕Щ閲忥細0 + * 鏁版嵁鑼冨洿锛�0~100% + * 鈥�0xFF鈥濊〃绀烘棤鏁� + * 2 绱娌硅�楋紙鎬绘补鑰楋級 DWORD L 鏁版嵁闀垮害锛�4bytes + * 绮惧害锛�0.5L per bit + * 鍋忕Щ閲忥細0 + * 鏁版嵁鑼冨洿锛�0~2,105,540,607.5L + * 鈥�0xFF,0xFF,0xFF,0xFF鈥濊〃绀烘棤鏁� + * 6 灏跨礌绠辨俯搴� BYTE 鈩� 鏁版嵁闀垮害锛�1bytes + * 绮惧害锛�1 鈩�/bit + * 鍋忕Щ閲忥細-40 + * 鏁版嵁鑼冨洿锛�-40~210鈩� + * 鈥�0xFF鈥濊〃绀烘棤鏁� + * 7 瀹為檯灏跨礌鍠峰皠閲� DWORD ml/h 鏁版嵁闀垮害锛�4bytes + * 绮惧害锛�0.01 ml/h per bit + * 鍋忕Щ閲忥細0 + * 鏁版嵁鑼冨洿锛�0 + * 鈥�0xFF,0xFF,0xFF,0xFF鈥濊〃绀烘棤鏁� + * 11 绱灏跨礌娑堣�楋紙鎬诲翱绱犳秷鑰楋級DWORD g 鏁版嵁闀垮害锛�4bytes + * 绮惧害锛�1 g per bit + * 鍋忕Щ閲忥細0 + * 鏁版嵁鑼冨洿锛�0 + * 鈥�0xFF,0xFF,0xFF,0xFF鈥濊〃绀烘棤鏁� + * 15 DPF 鎺掓皵娓╁害 WORD 鈩� 鏁版嵁闀垮害锛�2bytes + * 绮惧害锛�0.03125 鈩� per bit + * 鍋忕Щ閲忥細-273 + * 鏁版嵁鑼冨洿锛�-273~1734.96875鈩� + * 鈥�0xFF,0xFF鈥濊〃绀烘棤鏁� + */ +class SupplementDataFlow( + time: Date?, + serialNum: Int? +) : RealTimeData(time, serialNum) { + var obdEngineTorqueMode: Int? = null + var obdAcceleratorPedal: Double? = null + var obdTotalOilConsumption: Double? = null + var obdUreaBoxTemp: Double? = null + var obdUreaVolume: Double? = null + var obdTotalUreaConsume: Double? = null + var obdDpfTemp: Double? = null +} \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/obd/socket/bean/TimeCalibrationData.kt b/src/main/kotlin/com/flightfeather/obd/socket/bean/TimeCalibrationData.kt new file mode 100644 index 0000000..b94fde1 --- /dev/null +++ b/src/main/kotlin/com/flightfeather/obd/socket/bean/TimeCalibrationData.kt @@ -0,0 +1,8 @@ +package com.flightfeather.obd.socket.bean + +/** + * @author riku + * Date: 2019/9/12 + */ +class TimeCalibrationData : DataUnit() { +} \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/obd/socket/decoder/DataPackageDecoder.kt b/src/main/kotlin/com/flightfeather/obd/socket/decoder/DataPackageDecoder.kt new file mode 100644 index 0000000..589ab12 --- /dev/null +++ b/src/main/kotlin/com/flightfeather/obd/socket/decoder/DataPackageDecoder.kt @@ -0,0 +1,42 @@ +package com.flightfeather.obd.socket.decoder + +import com.flightfeather.obd.socket.bean.DataUnit +import com.flightfeather.obd.socket.eunm.ObdCommandUnit + +/** + * obd 绗竴灞傛暟鎹寘瑙g爜鍣� + * @author riku + * Date: 2019/9/12 + * + * 鏁版嵁绗竴灞傜粨鏋勫畾涔夊涓嬶細 + * 璧峰瀛楄妭 瀹氫箟 + * 0 璧峰绗� + * 2 鍛戒护鍗曞厓 绫诲瀷@see [ObdCommandUnit] + * 3 杞﹁締璇嗗埆鍙� + * 4 缁堢杞欢鐗堟湰鍙� + * 21 鏁版嵁鍔犲瘑鏂瑰紡 + * 22 鏁版嵁鍗曞厓闀垮害 + * 24 鏁版嵁鍗曞厓 瑙g爜鍣ˊsee [DataUnitDecoder] + * 鍊掓暟绗�1 鏍¢獙鐮� + */ +interface DataPackageDecoder { + + fun getHead(b: List<String>): String? + + fun getCommandUnit(b: List<String>): Int? + + fun getVinCode(b: List<String>): String? + + fun getSoftwareVersion(b: List<String>): Int? + + fun getEncryptionWay(b: List<String>): Int? + + fun getDataLength(b: List<String>): Int + + fun getDataUnit(b: List<String>): List<DataUnit> + + fun getCheckCode(b: List<String>): Int? + + fun toStringList(msg: String): List<String> + +} \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/obd/socket/decoder/DataUnitDecoder.kt b/src/main/kotlin/com/flightfeather/obd/socket/decoder/DataUnitDecoder.kt new file mode 100644 index 0000000..7ca4833 --- /dev/null +++ b/src/main/kotlin/com/flightfeather/obd/socket/decoder/DataUnitDecoder.kt @@ -0,0 +1,36 @@ +package com.flightfeather.obd.socket.decoder + +import com.flightfeather.obd.socket.bean.* +import com.flightfeather.obd.socket.eunm.ObdCommandUnit +import java.util.* + +/** + * obd 绗簩灞傛暟鎹崟鍏冭В鐮佸櫒 + * @author riku + * Date: 2019/9/12 + * + * 鏁版嵁鍗曞厓鎸夌収鍛戒护鍗曞厓鐨勭被鍨嬪叡鏈変互涓嬪嚑绉嶇被鍨嬶細 + * 鍛戒护鍗曞厓 @see [ObdCommandUnit] + * 缂栫爜(byte) 瀹氫箟 + * 0x01 杞﹁締鐧诲叆 + * 0x02 瀹炴椂淇℃伅涓婃姤 + * 0x03 琛ュ彂淇℃伅涓婃姤 + * 0x04 杞﹁締鐧诲嚭 + * 0x05 缁堢鏍℃椂 + * 0x06~0x7f 涓婅鏁版嵁绯荤粺棰勭暀 + */ +interface DataUnitDecoder { + + fun getCarRegisterData(b: List<String>): List<CarRegisterData> + + fun getRealTimeData(b: List<String>): List<RealTimeData> + + fun getReplacementData(b: List<String>): List<ReplacementData> + + fun getCarLogOutData(b: List<String>): List<CarLogOutData> + + fun getTimeCalibrationData(b: List<String>): List<TimeCalibrationData> + + fun decodeDataTime(b: List<String>): Date? + +} \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/obd/socket/decoder/RealTimeDataDecoder.kt b/src/main/kotlin/com/flightfeather/obd/socket/decoder/RealTimeDataDecoder.kt new file mode 100644 index 0000000..24e41e0 --- /dev/null +++ b/src/main/kotlin/com/flightfeather/obd/socket/decoder/RealTimeDataDecoder.kt @@ -0,0 +1,26 @@ +package com.flightfeather.obd.socket.decoder + +import com.flightfeather.obd.socket.bean.* +import com.flightfeather.obd.socket.eunm.ObdDataType +import java.util.* + +/** + * @author riku + * Date: 2019/9/15 + * 鏁版嵁鍗曞厓[DataUnit]涓紝绫诲瀷涓哄疄鏃朵俊鎭痆RealTimeData]鐨勮В鐮佸櫒 + * 鍏跺垎绫� @see [ObdDataType] + */ +interface RealTimeDataDecoder { + + fun getObdData(time: Date?, serialNum: Int, b: List<String>): ObdData? + + fun getEngineDataFlow(time: Date?, serialNum: Int, b: List<String>): EngineDataFlow? + + fun getSupplementDataFlow(time: Date?, serialNum: Int, b: List<String>): SupplementDataFlow? + + /** + * 鏍规嵁浼犲叆鐨勫垪琛紝榛樿绗竴浣嶄负 [ObdDataType]锛岃繑鍥炲搴旂殑鏁版嵁鍒楄〃 + */ + fun getDataListByDataType(list: List<String>): MutableList<String> + +} \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/obd/socket/decoder/VehicleDataDecoder.kt b/src/main/kotlin/com/flightfeather/obd/socket/decoder/VehicleDataDecoder.kt new file mode 100644 index 0000000..64aaf75 --- /dev/null +++ b/src/main/kotlin/com/flightfeather/obd/socket/decoder/VehicleDataDecoder.kt @@ -0,0 +1,35 @@ +package com.flightfeather.obd.socket.decoder + +import com.flightfeather.obd.socket.bean.ObdPackageData +import com.flightfeather.obd.socket.decoder.impl.DataPackageDecoderImpl +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Component +import javax.annotation.PostConstruct + +/** + * 杞﹁締 obd 鏁版嵁瑙g爜鍣� + * @author riku + * Date: 2019/9/12 + */ +class VehicleDataDecoder { + + private val dataPackageDecoder: DataPackageDecoder = DataPackageDecoderImpl() + + fun decode(msg: String): ObdPackageData { + val list = dataPackageDecoder.toStringList(msg) + dataPackageDecoder.run { + return ObdPackageData( + getHead(list), + getCommandUnit(list), + getVinCode(list), + getSoftwareVersion(list), + getEncryptionWay(list), + getDataLength(list), + getDataUnit(list), + getCheckCode(list) + ) + } + } + + +} \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/obd/socket/decoder/impl/DataPackageDecoderImpl.kt b/src/main/kotlin/com/flightfeather/obd/socket/decoder/impl/DataPackageDecoderImpl.kt new file mode 100644 index 0000000..5df0e21 --- /dev/null +++ b/src/main/kotlin/com/flightfeather/obd/socket/decoder/impl/DataPackageDecoderImpl.kt @@ -0,0 +1,98 @@ +package com.flightfeather.obd.socket.decoder.impl + +import com.flightfeather.obd.socket.bean.DataUnit +import com.flightfeather.obd.socket.decoder.DataPackageDecoder +import com.flightfeather.obd.socket.decoder.DataUnitDecoder +import com.flightfeather.obd.socket.eunm.ObdCommandUnit + +/** + * @author riku + * Date: 2019/9/12 + */ +class DataPackageDecoderImpl : DataPackageDecoder { + + private val dataUnitDecoder: DataUnitDecoder = DataUnitDecoderImpl() + + //fixme 2019.9.12: 鐜板湪鏈変袱绉嶆儏鍐碉紝1锛氭帴鏀跺埌鐨勫瓧绗︿覆鏄痓yte杞爜鍓嶇殑锛岄偅涔堝叾灏辫〃绀哄瓧绗︾殑ASCII鐮侊紱2锛氬彟涓�绉嶅氨鏄帴鏀跺埌鐨勬槸杞爜鍚庣殑瀛楃涓层�傜洰鍓嶅緟瀹� + + override fun getHead(b: List<String>): String? { + return if (b.size >= 2) { + "${b[0]}${b[1]}" + } 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鐮侊紝鍐嶈幏鍙栬浆鎹㈠悗鐨勫瓧绗︿覆 + val s = StringBuilder() + + for (i in 3..19) { + s.append(b[i].toIntOrNull(16)?.toChar()) + } + + return s.toString() + } + + override fun getSoftwareVersion(b: List<String>): Int? = if (b.size >= 21) { + b[20].toIntOrNull(16) + } else { + null + } + + override fun getEncryptionWay(b: List<String>): Int? = if (b.size >= 21) { + b[21].toIntOrNull(16) + } else { + null + } + + override fun getDataLength(b: List<String>): Int { + if (b.size < 24) return 0 + + val hexNum = "${b[22]}${b[23]}" + + return hexNum.toIntOrNull(16) ?: 0 + } + + override fun getDataUnit(b: List<String>): List<DataUnit> { + if (getDataLength(b) == 0 || b.size < 26) { + return emptyList() + } + + val unit = mutableListOf<String>() + for (i in 24..b.size - 2) { + 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) + else -> emptyList() + } + } + } + + override fun getCheckCode(b: List<String>): Int? { + return if (b.isNotEmpty()) { + b[b.size - 1].toIntOrNull(16) + } else { + null + } + } + + override fun toStringList(msg: String): List<String> { + return msg.split(" ") + } + +} \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/obd/socket/decoder/impl/DataUnitDecoderImpl.kt b/src/main/kotlin/com/flightfeather/obd/socket/decoder/impl/DataUnitDecoderImpl.kt new file mode 100644 index 0000000..139051c --- /dev/null +++ b/src/main/kotlin/com/flightfeather/obd/socket/decoder/impl/DataUnitDecoderImpl.kt @@ -0,0 +1,123 @@ +package com.flightfeather.obd.socket.decoder.impl + +import com.flightfeather.obd.socket.bean.* +import com.flightfeather.obd.socket.decoder.DataUnitDecoder +import com.flightfeather.obd.socket.decoder.RealTimeDataDecoder +import com.flightfeather.obd.socket.eunm.ObdDataType +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Component +import java.lang.StringBuilder +import java.util.* +import javax.annotation.PostConstruct + +/** + * @author riku + * Date: 2019/9/15 + */ +class DataUnitDecoderImpl : DataUnitDecoder { + + private var realTimeDataDecoder: RealTimeDataDecoder = RealTimeDataDecoderImpl() + + override fun getCarRegisterData(b: List<String>): List<CarRegisterData> { + val time = decodeDataTime(b) + + val serialNum = "${b[6]}${b[7]}".toInt(16) + + val simCode = StringBuilder() + for (i in 10 until b.size) { + simCode.append(b[i].toInt(16).toChar()) + } + + return mutableListOf(CarRegisterData(time, serialNum, simCode.toString())) + } + + override fun getRealTimeData(b: List<String>): List<RealTimeData> { + val time = decodeDataTime(b) + + //鍥芥爣娉�: 璧峰瀛楄妭涓�7 寮�濮嬬殑2涓瓧鑺傝〃绀� 娴佹按鍙� +// val serialNum = "${b[7]}${b[8]}".toInt(16) + + //涓婃捣娉�: 璧峰瀛楄妭涓�6 寮�濮嬬殑2涓瓧鑺傝〃绀� 娴佹按鍙� + val serialNum = "${b[6]}${b[7]}".toInt(16) + + val dataList = mutableListOf<String>().apply { addAll(b) } + //鍒犲幓鍓�6浣嶆椂闂� + for (i in 0..5) { + if (dataList.isNotEmpty()) dataList.removeAt(0) + } + + //fixme 2019.9.15 鐩墠涓ょ瑙勫垯鏈夊啿绐侊紝骞朵笖鍙粠鏁版嵁鍐呭鏃犳硶鍖哄垎銆傛殏鏃朵娇鐢� 鍥芥爣娉� + /* + * 鍒犲幓娴佹按鍙凤紝寰楀埌淇℃伅鏍囧織涓庝俊鎭綋鐨勭粍鍚� + * (鍥芥爣娉曪細鍘婚櫎鍓�6浣嶆椂闂村悗锛岃捣濮嬪瓧鑺備负1 寮�濮嬬殑2涓瓧鑺傝〃绀� 娴佹按鍙�) + */ +// if (dataList.size >= 2) dataList.removeAt(1) +// if (dataList.size >= 2) dataList.removeAt(1) + + /* + * 鍒犲幓娴佹按鍙凤紝寰楀埌淇℃伅鏍囧織涓庝俊鎭綋鐨勭粍鍚� + * (涓婃捣娉曪細鍘婚櫎鍓�6浣嶆椂闂村悗锛岃捣濮嬪瓧鑺備负0 寮�濮嬬殑2涓瓧鑺傝〃绀� 娴佹按鍙�) + */ + if (dataList.isNotEmpty()) dataList.removeAt(0) + if (dataList.isNotEmpty()) dataList.removeAt(0) + + val resultList = mutableListOf<RealTimeData>() + + /* + * 鏈�缁堝緱鍒扮殑鏁版嵁缁撴瀯涓� [ 淇℃伅绫诲瀷鏍囧織, 淇℃伅浣�, ...... , 淇℃伅绫诲瀷鏍囧織, 淇℃伅浣� ] + */ + while (dataList.isNotEmpty()) { + //寰楀埌鏈�鍓嶉潰鐨勪竴缁勪俊鎭被鍨�+淇℃伅浣撳垪琛� + val data = realTimeDataDecoder.getDataListByDataType(dataList) + if (data.isNotEmpty()) { + val r = when (data[0].toInt(16)) { + ObdDataType.ObdData.value -> realTimeDataDecoder.getObdData(time, serialNum, data) + ObdDataType.EngineDataFlow.value -> realTimeDataDecoder.getEngineDataFlow(time, serialNum, data) + ObdDataType.SupplementDataFlow.value -> realTimeDataDecoder.getSupplementDataFlow(time, serialNum, data) + else -> null + } + + if (r != null) { + resultList.add(r) + } + + for (i in 0 until data.size) { + if (dataList.isNotEmpty()) dataList.removeAt(0) + } + } + } + + return resultList + } + + override fun getReplacementData(b: List<String>): List<ReplacementData> = getRealTimeData(b) + + override fun getCarLogOutData(b: List<String>): List<CarLogOutData> { + val time = decodeDataTime(b) + + val serialNum = "${b[6]}${b[7]}".toInt(16) + + return mutableListOf(CarLogOutData(time, serialNum)) + } + + override fun getTimeCalibrationData(b: List<String>): List<TimeCalibrationData> = emptyList() + + override fun decodeDataTime(b: List<String>): Date? { + if (b.size < 6) { + return null + } + + val year = b[0].toInt(16) + 2000 + if (year < 2000 || year > 2099) return null + val month = b[1].toInt(16) + val day = b[2].toInt(16) + val hour = b[3].toInt(16) + val min = b[4].toInt(16) + val sec = b[5].toInt(16) + val cal = Calendar.getInstance().apply { + set(year, month - 1, day, hour, min, sec) + } + + return cal.time + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/obd/socket/decoder/impl/RealTimeDataDecoderImpl.kt b/src/main/kotlin/com/flightfeather/obd/socket/decoder/impl/RealTimeDataDecoderImpl.kt new file mode 100644 index 0000000..3acf5e8 --- /dev/null +++ b/src/main/kotlin/com/flightfeather/obd/socket/decoder/impl/RealTimeDataDecoderImpl.kt @@ -0,0 +1,163 @@ +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//浠h〃鏃犳晥 + } 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() + + 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 + } + +} \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/obd/socket/eunm/ObdCommandUnit.kt b/src/main/kotlin/com/flightfeather/obd/socket/eunm/ObdCommandUnit.kt new file mode 100644 index 0000000..c88fdc1 --- /dev/null +++ b/src/main/kotlin/com/flightfeather/obd/socket/eunm/ObdCommandUnit.kt @@ -0,0 +1,14 @@ +package com.flightfeather.obd.socket.eunm + +/** + * obd 鍛戒护鍗曞厓 + * @author riku + * Date: 2019/9/12 + */ +enum class ObdCommandUnit constructor(val value: Int) { + CarRegister(1), + RealTimeData(2), + ReplacementData(3), + CarLogOut(4), + TimeCalibration(5) +} \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/obd/socket/eunm/ObdDataType.kt b/src/main/kotlin/com/flightfeather/obd/socket/eunm/ObdDataType.kt new file mode 100644 index 0000000..b426851 --- /dev/null +++ b/src/main/kotlin/com/flightfeather/obd/socket/eunm/ObdDataType.kt @@ -0,0 +1,19 @@ +package com.flightfeather.obd.socket.eunm + +import com.flightfeather.obd.socket.bean.* +/** + * @author riku + * Date: 2019/9/15 + * 瀹炴椂淇℃伅[RealTimeData]鍜岃ˉ鍙戜俊鎭痆ReplacementData]涓殑鏁版嵁绫诲瀷 + * 绫诲瀷缂栫爜 璇存槑 + * 0x01 OBD 淇℃伅 + * 0x02 鏁版嵁娴佷俊鎭� + * 0x03-0x7F 棰勭暀 + * 0x80 琛ュ厖鏁版嵁娴� + * 0x81~0xFE 鐢ㄦ埛鑷畾涔� + */ +enum class ObdDataType constructor(val value: Int){ + ObdData(1), + EngineDataFlow(2), + SupplementDataFlow(128) +} \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 2b6df51..00493e3 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -17,6 +17,7 @@ not-empty: false identity: MYSQL +#鏁版嵁搴撳垎椤甸厤缃� pagehelper: helperDialect: mysql reasonable: true diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml new file mode 100644 index 0000000..7353e5a --- /dev/null +++ b/src/main/resources/log4j2.xml @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 6涓紭鍏堢骇浠庨珮鍒颁綆渚濇涓猴細OFF銆丗ATAL銆丒RROR銆乄ARN銆両NFO銆丏EBUG銆乀RACE銆� ALL銆� + 濡傛灉璁剧疆浼樺厛绾т负WARN锛岄偅涔圤FF銆丗ATAL銆丒RROR銆乄ARN 4涓骇鍒殑log鑳芥甯歌緭鍑� + 璁剧疆涓篛FF 琛ㄧず涓嶈褰昹og4j2鏈韩鐨勬棩蹇楋紝 + --> + +<!-- status锛氱敤鏉ユ寚瀹歭og4j鏈韩鐨勬墦鍗版棩蹇楃骇鍒�,monitorInterval:鎸囧畾log4j鑷姩閲嶆柊閰嶇疆鐨勭洃娴嬮棿闅旀椂闂� --> +<configuration status="INFO" monitorInterval="30"> + <!-- 鑷繁璁剧疆灞炴�э紝鍚庨潰閫氳繃${}鏉ヨ闂� --> + <properties> + <property name="LOG_HOME">../obdLogs</property> + </properties> + + <appenders> + <!--Appender 1. 杈撳嚭鍒癈onsole鎺у埗鍙帮紝鎸囧畾杈撳嚭鏍煎紡鍜岃繃婊ゅ櫒绛夌骇涓篒NFO --> + <Console name="Console" target="SYSTEM_OUT"> + <!--ThresholdFilter鎸囧畾鏃ュ織娑堟伅鐨勮緭鍑烘渶浣庡眰娆�--> + <ThresholdFilter level="ALL" onMatch="ACCEPT" onMismatch="DENY"/> + <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/> + </Console> + + <!--Appender 2. 杈撳嚭鍒版粴鍔ㄤ繚瀛樼殑鏂囦欢, 瑙﹀彂淇濆瓨鏃ュ織鏂囦欢鐨勬潯浠舵槸鏃ュ織鏂囦欢澶т簬3KB锛屽彧淇濆瓨鏈�鏂扮殑10涓棩蹇�--> + <File name="allLog" fileName="${LOG_HOME}/all.log"> + <ThresholdFilter level="ALL" onMatch="ACCEPT" onMismatch="DENY"/> + <PatternLayout charset="UTF-8" pattern="%d{yyyy.MM.dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/> + </File> + + + <!--Appender 3. 杈撳嚭鍒版粴鍔ㄤ繚瀛樼殑鏂囦欢, 瑙﹀彂淇濆瓨鏃ュ織鏂囦欢鐨勬潯浠舵槸鏃ュ織鏂囦欢澶т簬3KB锛屽彧淇濆瓨鏈�鏂扮殑10涓棩蹇�--> + <RollingFile name="debugLog" fileName="${LOG_HOME}/debug.log" filePattern="${LOG_HOME}/debug-%i.log"> + <ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/> + <PatternLayout charset="UTF-8" pattern="[%-5level][%d{yyyy-MM-dd HH:mm:ss}][%F:%L] - %m%n"/> + <SizeBasedTriggeringPolicy size="3KB"/> + <!-- DefaultRolloverStrategy 涓殑鍙傛暟max锛屽彲浠ラ檺鍒� SizeBasedTriggeringPolicy涓璼ize瓒呭嚭鍚庯紝鍙繚鐣檓ax涓瓨妗�--> + <DefaultRolloverStrategy max="10"/> + </RollingFile> + + <!--Appender 4. 杈撳嚭鍒版粴鍔ㄤ繚瀛樼殑鏂囦欢, 瑙﹀彂淇濆瓨鏃ュ織鏂囦欢鐨勬潯浠舵槸姣忓垎閽熺涓�娆$殑鏃ュ織浜嬩欢銆侲RROR鏃ュ織鏄寜鍒嗛挓浜х敓鏃ュ織 --> + <RollingFile name="errorLog" fileName="${LOG_HOME}/error.log" filePattern="${LOG_HOME}/error-%d{yyyy-MM-dd_HH-mm}.log"> + <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/> + <PatternLayout charset="UTF-8" pattern="[%-5level][%d{yyyy-MM-dd HH:mm:ss}][%C:%F:%L] - %m%n"/> + <TimeBasedTriggeringPolicy/> + </RollingFile> + + <RollingFile name="RollingFile" fileName="${LOG_HOME}/rar.log" filePattern="${LOG_HOME}/$${date:yyyy-MM}/${FILE_NAME}-%d{MM-dd-yyyy}-%i.log.gz"> + <PatternLayout charset="UTF-8" pattern="%d{yyyy-MM-dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/> + <!--鏃ュ織鏂囦欢鏈�澶у�� 绗簩澶╁帇缂�--> + <Policies> + <TimeBasedTriggeringPolicy/> + <SizeBasedTriggeringPolicy size="10 MB"/> + </Policies> + </RollingFile> + + + </appenders> + <!--root 榛樿鍔犺浇--> + <loggers> + <root level="DEBUG"> + <appender-ref ref="Console"/> + <!--<appender-ref ref="allLog"/>--> + <appender-ref ref="debugLog"/> + <appender-ref ref="errorLog"/> + <appender-ref ref="RollingFile"/> + </root> + </loggers> +</configuration> \ No newline at end of file diff --git a/src/test/kotlin/com/flightfeather/obd/ObdApplicationTests.kt b/src/test/kotlin/com/flightfeather/obd/ObdApplicationTests.kt index 93dea64..db1a9dc 100644 --- a/src/test/kotlin/com/flightfeather/obd/ObdApplicationTests.kt +++ b/src/test/kotlin/com/flightfeather/obd/ObdApplicationTests.kt @@ -6,6 +6,7 @@ import com.google.gson.Gson import org.junit.Test import org.junit.runner.RunWith +import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import org.springframework.test.context.junit4.SpringRunner @@ -35,4 +36,14 @@ println(map.cmdCode) } + @Test + fun logTest() { + val log = LoggerFactory.getLogger(javaClass) + log.trace("trace") + log.debug("debug") + log.warn("warn") + log.info("info") + log.error("error") + } + } diff --git a/src/test/kotlin/com/flightfeather/obd/Test.kt b/src/test/kotlin/com/flightfeather/obd/Test.kt new file mode 100644 index 0000000..8b067b2 --- /dev/null +++ b/src/test/kotlin/com/flightfeather/obd/Test.kt @@ -0,0 +1,88 @@ +package com.flightfeather.obd + +import org.junit.Test +import java.nio.charset.Charset +import java.text.SimpleDateFormat +import java.util.* + +/** + * @author riku + * Date: 2019/9/12 + */ +class Test { + + @Test + fun foo1() { + val b = ByteArray(20) {8} + println(b[18]) + } + + @Test + fun foo2() { + val b = ByteArray(1){97} + val s = "a" + println() + } + + @Test + fun foo3() { + val hexNum = "ff" + val length = hexNum.toInt(16) + println(length) + } + + @Test + fun foo4() { + val h = "0101" + val byte = 0xff + val b = h.toInt(16) + println(b) + } + + @Test + fun foo5() { + val s = "23 23 30 30 30 30 30 35 33 31 36 30 38 30 31 30 35 33 36" + val sb = StringBuilder() + val ascii = s.split(" ") + ascii.forEach { + sb.append(it.toIntOrNull(16)?.toChar()) + } + println(sb.toString()) + } + + @Test + fun foo6() { + val cal = Calendar.getInstance().apply { + set(2019, 9, 15, 23, 16, 59) + } + + println(SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(cal.time)) + } + + @Test + fun foo7() { + val a = "0AAF".toIntOrNull(16)?.toString(2) + println(a) + } + + @Test + fun foo8() { + val byte = ByteArray(2) + byte[0] = 0x23 + byte[1] = 0x23 + + byte[0].toString(16) + } + + @Test + fun foo9() { + val b = 128.toByte() + var a = 0 + if (b < 0) { + a = b + 256 + } else { + a = b.toInt() + } + println(b.toString(16)) + } +} \ No newline at end of file -- Gitblit v1.9.3