desc:解析传感器数据

main
xiaowusky 2 years ago
parent 5cfa300050
commit 926bb54a18

@ -19,9 +19,32 @@ android {
}
}
signingConfigs {
debug {
storeFile file(rootProject.ext.sign.keystore_path)
storePassword rootProject.ext.sign.keystore_pwd
keyAlias rootProject.ext.sign.keystore_alias
keyPassword rootProject.ext.sign.keystore_pwd
}
release {
storeFile file(rootProject.ext.sign.keystore_path)
storePassword rootProject.ext.sign.keystore_pwd
keyAlias rootProject.ext.sign.keystore_alias
keyPassword rootProject.ext.sign.keystore_pwd
}
}
viewBinding {
enabled = true
}
buildTypes {
debug {
signingConfig signingConfigs.debug
}
release {
signingConfig signingConfigs.release
}
}
}
@ -69,4 +92,6 @@ dependencies {
annotationProcessor 'androidx.lifecycle:lifecycle-compiler:2.0.0'
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
implementation 'com.aill:AndroidSerialPort:1.0.8'
}

@ -34,18 +34,6 @@ object TestUtils {
TxtOverlay.setShowTip("co2:50%@co:44%")
PushHelper.setPushUrl("rtsp://192.168.5.17:554/123")
GlobalScope.launch() {
// 插入类型
val typeDao = DBUtils.gasTypeDao()
val all = typeDao.getAll()
if (all.isNotEmpty()) {
return@launch
}
val list = mutableListOf<GasType>()
list.add(GasType("CO", "", false))
list.add(GasType("CO2", "", false))
list.add(GasType("O2", "", false))
typeDao.insertAll(list)
// 构造气体数据
val timeMillis = System.currentTimeMillis()

@ -4,12 +4,12 @@ import com.common.commonlib.CommonApplication
import com.common.commonlib.db.DBUtils
import com.common.commonlib.db.dao.WarningDao
import com.common.commonlib.db.entity.Warning
import com.lztek.toolkit.Lztek
import com.yinuo.safetywatcher.TestUtils
import com.yinuo.safetywatcher.watcher.constant.CAMERA_DNS
import com.yinuo.safetywatcher.watcher.constant.CAMERA_GATEWAY
import com.yinuo.safetywatcher.watcher.constant.CAMERA_IP
import com.yinuo.safetywatcher.watcher.constant.CAMERA_NETMASK
import com.yinuo.safetywatcher.watcher.port.cmd.GasPortStatus
import com.yinuo.safetywatcher.watcher.utils.LztekUtil
import com.yinuo.safetywatcher.watcher.wifi.WiFiConfig
import com.yinuo.safetywatcher.watcher.wifi.WiFiModule
@ -23,7 +23,7 @@ import java.io.File
class App : CommonApplication() {
override fun onCreate() {
super.onCreate()
LztekUtil.setObject(Lztek.create(this))
// LztekUtil.setObject(Lztek.create(this))
ipConfig()
wifiConfig()
tryFixDbData()
@ -73,7 +73,7 @@ class App : CommonApplication() {
val gasTypeDao = DBUtils.gasTypeDao()
val all = gasTypeDao.getAll()
all.onEach { gasType ->
gasType.online = false
gasType.status = GasPortStatus.OUTLINE
gasTypeDao.insert(gasType)
}
}.await()

@ -1,24 +1,20 @@
package com.yinuo.safetywatcher.watcher.port
import android.os.Handler
import android.os.Looper
import com.common.commonlib.db.DBUtils
import com.common.commonlib.db.entity.GasType
import com.yinuo.library.vlc.TxtOverlay
import com.common.serialport.ComMultiPortUtils
import com.yinuo.safetywatcher.watcher.port.cmd.CMD
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Runnable
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
object GasUtils {
private const val BAUD_RATE = 9600
private const val FULL_MSG_SIZE = 9
private const val CHECK_TIME = 10000L
private val mPortFlags = booleanArrayOf(false, false, false, false)
private val mPortRunnable = hashMapOf<Int, FlagRunnable>()
private val mHandler = Handler(Looper.getMainLooper())
private const val PORT_PATH = "/dev/ttyS1"
const val FULL_MSG_SIZE = 9
const val CHECK_TIME = 10000L
private const val READ_MSG_INTERVAL = 500L
private var mInitFlag = false
fun initPort() {
openPorts()
@ -26,56 +22,32 @@ object GasUtils {
}
private fun openPorts() {
if (!mPortFlags[0]) {
PlatformMultiPortUtils.openPort("/dev/tyyS0", BAUD_RATE) {
if (it.isNotEmpty() && it.size >= FULL_MSG_SIZE) {
val checkSum = getCheckSum(it)
// 校验通过
if (checkSum == it[8]) {
val gasName = it[1]
val gasUnit = it[2]
val gasValue: Double = (it[4] * 256 + it[5]) / 100.00
setFlag(0, gasName, "/dev/tyyS0")
// TODO
TxtOverlay.setShowTip("")
}
}
if (!mInitFlag) {
ComMultiPortUtils.openPort(PORT_PATH, BAUD_RATE) {
mInitFlag = true
ParseHelper.parse(it)
}
}
if (!mPortFlags[1]) {
PlatformMultiPortUtils.openPort("/dev/tyyS1", BAUD_RATE) {}
}
if (!mPortFlags[2]) {
PlatformMultiPortUtils.openPort("/dev/tyyS2", BAUD_RATE) {}
}
if (!mPortFlags[3]) {
PlatformMultiPortUtils.openPort("/dev/tyyS3", BAUD_RATE) {}
readGasMsg()
}
}
@OptIn(DelicateCoroutinesApi::class)
private fun updateGasTypeDb(gasName: Byte, port: String, online: Boolean) {
GlobalScope.launch {
val typeDao = DBUtils.gasTypeDao()
val gasType = typeDao.getByName(gasName.toString())
gasType?.online = online
typeDao.insert(gasType ?: GasType(gasName.toString(), port, online))
}
}
private fun setFlag(index: Int, gasName: Byte, port: String) {
var flagRunnable = mPortRunnable[index]
if (flagRunnable == null) {
flagRunnable = FlagRunnable(index, gasName, port)
mPortRunnable[index] = flagRunnable
/**
* 读取气体浓度
*/
private fun readGasMsg() {
GlobalScope.launch(Dispatchers.IO) {
while (true) {
// 延时一段时间后,发送指令读取气体数据
delay(READ_MSG_INTERVAL)
ComMultiPortUtils.sendMsg(PORT_PATH, CMD.O2)
delay(READ_MSG_INTERVAL)
ComMultiPortUtils.sendMsg(PORT_PATH, CMD.CH4)
delay(READ_MSG_INTERVAL)
ComMultiPortUtils.sendMsg(PORT_PATH, CMD.CO)
delay(READ_MSG_INTERVAL)
ComMultiPortUtils.sendMsg(PORT_PATH, CMD.H2S)
}
}
mHandler.removeCallbacks(flagRunnable)
// 如果一段时间内没有收到消息,认为连接断开
mHandler.postDelayed(flagRunnable, CHECK_TIME)
mPortFlags[index] = true
updateGasTypeDb(gasName, port, true)
}
// 监控串口状态
@ -91,27 +63,4 @@ object GasUtils {
}
}
}
// 计算校验值
private fun getCheckSum(bytes: ByteArray?): Byte {
var sum: Int = 0
bytes?.forEachIndexed { index, byte ->
if (index != 0 && index < FULL_MSG_SIZE - 1) {
sum += (byte.toInt() and 0xff)
}
}
return (sum.inv() + 1).toByte()
}
class FlagRunnable(
private val index: Int,
private val gasName: Byte,
private val port: String
) : Runnable {
override fun run() {
PlatformMultiPortUtils.release(port)
mPortFlags[index] = false
updateGasTypeDb(gasName, "", false)
}
}
}

@ -0,0 +1,144 @@
package com.yinuo.safetywatcher.watcher.port
import android.os.Handler
import android.os.Looper
import com.common.commonlib.db.DBUtils
import com.common.commonlib.db.entity.GasType
import com.common.serialport.utils.HexUtils
import com.yinuo.library.vlc.utils.LogUtils
import com.yinuo.safetywatcher.watcher.port.cmd.GasPortStatus
import com.yinuo.safetywatcher.watcher.port.cmd.ResponseHelper
import com.yinuo.safetywatcher.watcher.port.cmd.getGasTypeByCode
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlin.math.pow
object ParseHelper {
private val mPortRunnable = hashMapOf<Int, FlagRunnable>()
private val mHandler = Handler(Looper.getMainLooper())
fun parse(it: ByteArray) {
if (it.isNotEmpty() && it.size >= GasUtils.FULL_MSG_SIZE) {
// val checkSum = getCheckSum(it)
// // 校验通过
// if (checkSum == it[8]) {
// val gasName = it[1]
// val gasUnit = it[2]
// val gasValue: Double = (it[4] * 256 + it[5]) / 100.00
// setFlag(0, gasName, "/dev/tyyS0")
//
// // TODO
// TxtOverlay.setShowTip("")
// }
LogUtils.v("receive msg, ${HexUtils.byteArrToHex(it)}")
val gasIndex = it[0].toInt()
val status = it[14].toInt()
val gasType = getGasTypeByCode(it[19].toInt())
when (status) {
// 预热
0 -> {
updateGasTypeDb(gasType, GasPortStatus.PRE_HOT)
setFlag(gasIndex, gasType)
}
// 正常
1 -> {
updateGasTypeDb(gasType, GasPortStatus.OK)
setFlag(gasIndex, gasType)
parseGasData(gasType, it)
}
// 故障
2, 3, 7 -> {
updateGasTypeDb(gasType, GasPortStatus.ERROR)
setFlag(gasIndex, gasType)
}
else -> {
LogUtils.v("unKnow status, do nothing")
}
}
}
}
private fun parseGasData(gasType: String, it: ByteArray) {
val unitHex: String = HexUtils.byteArrToHex(it, 3, 3 + 2)
val unitToLong: Long = HexUtils.hexToLong(unitHex)
// 10000000000000
var unitBinaryString = java.lang.Long.toBinaryString(unitToLong)
LogUtils.v("receive msg $gasType, unitBinaryString 1 = $unitBinaryString")
if (unitBinaryString.length < 16) {
val offset = 16 - unitBinaryString.length
repeat(offset){
unitBinaryString = "0" + unitBinaryString;
}
}
LogUtils.v("receive msg, unitBinaryString 2 = $unitBinaryString")
unitBinaryString = unitBinaryString.reversed()
LogUtils.v("receive msg, unitBinaryString 3 = $unitBinaryString")
//小数点
val subSequence = unitBinaryString.subSequence(8, 12)
val pointNum = ResponseHelper.getPointNum(subSequence)
LogUtils.v("receive msg, 小数点 = $subSequence$pointNum")
// 单位
val subSequence2 = unitBinaryString.subSequence(12, 16)
val unit = ResponseHelper.getGasUnit(subSequence2)
LogUtils.v("receive msg, 单位 = $subSequence2$unit")
val c17 = unitBinaryString[6].toString()
val c18 = unitBinaryString[7].toString()
// 气体浓度
val valueHex: String = HexUtils.byteArrToHex(it, 5, 5 + 2)
val valueHexLong: Long = HexUtils.hexToLong(valueHex)
// 浓度
val value =
c18.plus(c17).plus(java.lang.Long.toBinaryString(valueHexLong)).toInt(2) / 10.0.pow(
pointNum
)
LogUtils.v("receive msg, 浓度 = $c18$c17, | $valueHex, $valueHexLong, | $value")
// 量程
val rangHex: String = HexUtils.byteArrToHex(it, 11, 11 + 2)
val rangHexLong: Long = HexUtils.hexToLong(rangHex)
LogUtils.v("receive msg, 量程 = $rangHex$rangHexLong")
}
/**
* 更新数据库
*/
@OptIn(DelicateCoroutinesApi::class)
private fun updateGasTypeDb(gasName: String, status: Int) {
GlobalScope.launch {
val typeDao = DBUtils.gasTypeDao()
val gasType = typeDao.getByName(gasName)
typeDao.insert(gasType ?: GasType(gasName, status))
}
}
/**
* 启动离线检查
*/
private fun setFlag(index: Int, gasName: String) {
var flagRunnable = mPortRunnable[index]
if (flagRunnable != null) {
mHandler.removeCallbacks(flagRunnable)
}
flagRunnable = FlagRunnable(gasName)
mPortRunnable[index] = flagRunnable
// 如果一段时间内没有收到消息,认为连接断开
mHandler.postDelayed(flagRunnable, GasUtils.CHECK_TIME)
}
/**
* 离线检查
*/
class FlagRunnable(
private val gasName: String
) : Runnable {
override fun run() {
updateGasTypeDb(gasName, GasPortStatus.OUTLINE)
}
}
}

@ -0,0 +1,10 @@
package com.yinuo.safetywatcher.watcher.port.cmd
class CMD {
companion object {
val O2 = byteArrayOf(GasAddress.ADR_O2.toByte(), 0x03, 0x00, 0x00, 0x00, 0x0A).crc16()
val CH4 = byteArrayOf(GasAddress.ADR_CH4.toByte(), 0x03, 0x00, 0x00, 0x00, 0x0A).crc16()
val CO = byteArrayOf(GasAddress.ADR_CO.toByte(), 0x03, 0x00, 0x00, 0x00, 0x0A).crc16()
val H2S = byteArrayOf(GasAddress.ADR_H2S.toByte(), 0x03, 0x00, 0x00, 0x00, 0x0A).crc16()
}
}

@ -0,0 +1,50 @@
package com.yinuo.safetywatcher.watcher.port.cmd
const val BITS_OF_BYTE = 8
const val POLYNOMIAL = 0xA001
const val INITIAL_VALUE = 0xFFFF
const val FF = 0xFF
fun ByteArray.crc16(): ByteArray {
var res = INITIAL_VALUE
for (data in this) {
res = res xor (data.toInt() and FF)
for (i in 0 until BITS_OF_BYTE) {
res = if (res and 0x0001 == 1) res shr 1 xor POLYNOMIAL else res shr 1
}
}
val lowByte: Byte = (res shr 8 and FF).toByte()
val highByte: Byte = (res and FF).toByte()
return this.plus(highByte).plus(lowByte)
}
fun IntArray.crc16(): ByteArray {
val byteArray = ByteArray(this.size + 2)
var res = INITIAL_VALUE
for (index in this.indices) {
res = res xor this[index]
byteArray[index] = this[index].toByte()
for (i in 0 until BITS_OF_BYTE) {
res = if (res and 0x0001 == 1) res shr 1 xor POLYNOMIAL else res shr 1
}
}
val lowByte: Byte = (res shr 8 and FF).toByte()
val highByte: Byte = (res and FF).toByte()
byteArray[this.size] = highByte
byteArray[this.size + 1] = lowByte
return byteArray
}
fun ByteArray.crc16Verify(): Boolean {
if (this.size < 3) throw RuntimeException("数组长度不合法")
var res = INITIAL_VALUE
for (index in 0..this.size - 3) {
res = res xor (this[index].toInt() and FF)
for (i in 0 until BITS_OF_BYTE) {
res = if (res and 0x0001 == 1) res shr 1 xor POLYNOMIAL else res shr 1
}
}
val lowByte: Byte = (res shr 8 and FF).toByte()
val highByte: Byte = (res and FF).toByte()
return highByte == this[this.size - 2] && lowByte == this[this.size - 1]
}

@ -0,0 +1,18 @@
package com.yinuo.safetywatcher.watcher.port.cmd
import androidx.annotation.IntDef
@IntDef(
GasAddress.ADR_CH4,
GasAddress.ADR_O2,
GasAddress.ADR_CO,
GasAddress.ADR_H2S
)
annotation class GasAddress {
companion object {
const val ADR_CH4 = 0X01
const val ADR_O2 = 0X02
const val ADR_CO = 0X03
const val ADR_H2S = 0X04
}
}

@ -0,0 +1,19 @@
package com.yinuo.safetywatcher.watcher.port.cmd
import androidx.annotation.IntDef
@IntDef(
GasPortStatus.PRE_HOT,
GasPortStatus.OK,
GasPortStatus.ERROR,
GasPortStatus.OUTLINE
)
annotation class GasPortStatus {
companion object {
const val PRE_HOT = 0
const val OK = 1
const val ERROR = 2
const val OUTLINE = 3
}
}

@ -0,0 +1,19 @@
package com.yinuo.safetywatcher.watcher.port.cmd
enum class GasType(val code: Int, val desc: String) {
CO(5, "CO"),
CH4(11, "CH4"),
O2(67, "O2"),
H2S(52, "H2S")
}
fun getGasTypeByCode(code: Int): String {
val codes = GasType.values();
codes.forEach {
if (code == it.code) {
return it.desc;
}
}
return ""
}

@ -0,0 +1,30 @@
package com.yinuo.safetywatcher.watcher.port.cmd
object ResponseHelper {
/**
* 小数点个数
*/
fun getPointNum(sequence: CharSequence): Int {
return when (sequence) {
"0000" -> 0
"0100" -> 1
"1000" -> 2
"1100" -> 3
else -> 0
}
}
/**
* 气体单位
*/
fun getGasUnit(sequence: CharSequence): String {
return when (sequence) {
"0000" -> "ppm"
"0010" -> "%LEL"
"0100" -> "%VOL"
"0110" -> "mg/m3"
"1000" -> "ppb"
else -> ""
}
}
}

@ -7,6 +7,7 @@ import com.common.commonlib.db.entity.GasType
import com.yinuo.safetywatcher.R
import com.yinuo.safetywatcher.databinding.LayoutItemSensorBinding
import com.yinuo.safetywatcher.watcher.base.BaseRvAdapter
import com.yinuo.safetywatcher.watcher.port.cmd.GasPortStatus
import com.yinuo.safetywatcher.watcher.ui.SensorSettingActivity
class SensorAdapter :
@ -35,17 +36,29 @@ class SensorAdapter :
}
binding.sensorName.text = data.nickName ?: "${data.type}传感器"
val state = data.online
val state = data.status
binding.sensorStatus.text = context.getText(getShowStatus(state))
binding.sensorStatus.setTextColor(context.getColor(getShowStatusColor(state)))
}
private fun getShowStatusColor(state: Boolean): Int {
return if (state) R.color.color_ok else R.color.color_error
private fun getShowStatusColor(state: Int): Int {
return when(state){
GasPortStatus.PRE_HOT -> R.color.color_prehot
GasPortStatus.OK -> R.color.color_ok
GasPortStatus.ERROR -> R.color.color_error
GasPortStatus.OUTLINE -> R.color.color_offline
else -> R.color.color_offline
}
}
private fun getShowStatus(state: Boolean): Int {
return if (state) R.string.status_ok else R.string.status_offline
private fun getShowStatus(state: Int): Int {
return when(state){
GasPortStatus.PRE_HOT -> R.string.status_prehot
GasPortStatus.OK -> R.string.status_ok
GasPortStatus.ERROR -> R.string.status_error
GasPortStatus.OUTLINE -> R.string.status_offline
else -> R.string.status_offline
}
}
}
}

@ -21,6 +21,7 @@
<color name="_202A45">#202A45</color>
<color name="color_ok">#01E41C</color>
<color name="color_prehot">#f6d365</color>
<color name="color_offline">#999999</color>
<color name="color_error">#E40101</color>

@ -31,6 +31,7 @@
<string name="status_ok">正常</string>
<string name="status_offline">离线</string>
<string name="status_prehot">预热</string>
<string name="status_error">故障</string>
<string name="sensor_warn_setting_txt">传感器报警值设定</string>
<string name="save">保存</string>

@ -1,6 +1,6 @@
project.ext {
sign = [
keystore_path : "../signature/innovationapp.jks",
keystore_path : "../innovationapp.jks",
keystore_pwd : "123456",
keystore_alias: "yinuo"
]

Binary file not shown.

@ -7,7 +7,6 @@ import androidx.room.PrimaryKey
@Entity(tableName = "gas_type")
data class GasType(
@PrimaryKey @ColumnInfo(name = "gas_name") var type: String,
@ColumnInfo(name = "port_path") var port: String,
@ColumnInfo(name = "online_flag") var online: Boolean,
@ColumnInfo(name = "status") var status: Int = 3,
@ColumnInfo(name = "nick_name") var nickName: String? = null,
)

@ -42,13 +42,14 @@ class EasySerialPort<T>(
while (mStartReceiveMsg) {
try {
val ips = helper?.inputStream()
val readByte = ips?.available()?.let { ByteArray(it) }
readByte?.let {
val size = ips.read(it)
val readByte = ByteArray(25)
val size = ips?.read(readByte)
if (size != null) {
if (size > 0) {
mReceiver.invoke(readByte)
}
}
Thread.sleep(50L)
} catch (e: IOException) {
Log.e(
"EasySerialPort",
@ -67,25 +68,40 @@ class EasySerialPort<T>(
* 写消息
*/
open fun write(data: ByteArray) {
val task = SendMsgTask(data) {
try {
val outputStream = helper?.outputStream()
outputStream?.write(it)
outputStream?.flush()
} catch (e: IOException) {
Log.e(
"EasySerialPort",
"write msg error; path = " + portPath + ", error msg = " + e.message
)
e.printStackTrace()
if (mAutoRetryConnect) {
closePort()
openSerialPort()
}
// val task = SendMsgTask(data) {
// try {
// val outputStream = helper?.outputStream()
// outputStream?.write(it)
// outputStream?.flush()
// } catch (e: IOException) {
// Log.e(
// "EasySerialPort",
// "write msg error; path = " + portPath + ", error msg = " + e.message
// )
// e.printStackTrace()
// if (mAutoRetryConnect) {
// closePort()
// openSerialPort()
// }
// }
// }
// task.attachScheduler(mTaskScheduler)
// task.enqueue()
try {
val outputStream = helper?.outputStream()
outputStream?.write(data)
outputStream?.flush()
} catch (e: IOException) {
Log.e(
"EasySerialPort",
"write msg error; path = " + portPath + ", error msg = " + e.message
)
e.printStackTrace()
if (mAutoRetryConnect) {
closePort()
openSerialPort()
}
}
task.attachScheduler(mTaskScheduler)
task.enqueue()
}
/**

@ -1,139 +0,0 @@
package com.common.serialport.utils;
import java.util.ArrayList;
import java.util.List;
/**
*
* Created by Administrator on 2016/6/2.
*/
public class DataUtils {
//-------------------------------------------------------
// 判断奇数或偶数位运算最后一位是1则为奇数为0是偶数
public static int isOdd(int num) {
return num & 1;
}
//-------------------------------------------------------
//Hex字符串转int
public static int HexToInt(String inHex) {
return Integer.parseInt(inHex, 16);
}
public static String IntToHex(int intHex){
return Integer.toHexString(intHex);
}
//-------------------------------------------------------
//Hex字符串转byte
public static byte HexToByte(String inHex) {
return (byte) Integer.parseInt(inHex, 16);
}
//-------------------------------------------------------
//1字节转2个Hex字符
public static String Byte2Hex(Byte inByte) {
return String.format("%02x", new Object[]{inByte}).toUpperCase();
}
//-------------------------------------------------------
//字节数组转转hex字符串
public static String ByteArrToHex(byte[] inBytArr) {
StringBuilder strBuilder = new StringBuilder();
for (byte valueOf : inBytArr) {
strBuilder.append(Byte2Hex(Byte.valueOf(valueOf)));
strBuilder.append(" ");
}
return strBuilder.toString();
}
//-------------------------------------------------------
//字节数组转转hex字符串可选长度
public static String ByteArrToHex(byte[] inBytArr, int offset, int byteCount) {
StringBuilder strBuilder = new StringBuilder();
int j = byteCount;
for (int i = offset; i < j; i++) {
strBuilder.append(Byte2Hex(Byte.valueOf(inBytArr[i])));
}
return strBuilder.toString();
}
//-------------------------------------------------------
//转hex字符串转字节数组
public static byte[] HexToByteArr(String inHex) {
byte[] result;
int hexlen = inHex.length();
if (isOdd(hexlen) == 1) {
hexlen++;
result = new byte[(hexlen / 2)];
inHex = "0" + inHex;
} else {
result = new byte[(hexlen / 2)];
}
int j = 0;
for (int i = 0; i < hexlen; i += 2) {
result[j] = HexToByte(inHex.substring(i, i + 2));
j++;
}
return result;
}
/**
*
*
* @param inputString
* @param length
* @return
*/
public static List<String> getDivLines(String inputString, int length) {
List<String> divList = new ArrayList<>();
int remainder = (inputString.length()) % length;
// 一共要分割成几段
int number = (int) Math.floor((inputString.length()) / length);
for (int index = 0; index < number; index++) {
String childStr = inputString.substring(index * length, (index + 1) * length);
divList.add(childStr);
}
if (remainder > 0) {
String cStr = inputString.substring(number * length, inputString.length());
divList.add(cStr);
}
return divList;
}
/**
*
*
* @param val value
* @return
*/
public static String twoByte(String val) {
if (val.length() > 4) {
val = val.substring(0, 4);
} else {
int l = 4 - val.length();
for (int i = 0; i < l; i++) {
val = "0" + val;
}
}
return val;
}
/**
*
*
* @param cmd
* @return
*/
public static String sum(String cmd) {
List<String> cmdList = DataUtils.getDivLines(cmd, 2);
int sumInt = 0;
for (String c : cmdList) {
sumInt += DataUtils.HexToInt(c);
}
String sum = DataUtils.IntToHex(sumInt);
sum = DataUtils.twoByte(sum);
cmd += sum;
return cmd.toUpperCase();
}
}

@ -0,0 +1,146 @@
package com.common.serialport.utils;
/**
*
*/
public class HexUtils {
/**
* 10
*
* @param num
* @return
*/
static public int isOdd(int num) {
return num & 0x1;
}
/**
* HexLong
*
* @param inHex
* @return
*/
static public long hexToLong(String inHex) {
return Long.parseLong(inHex, 16);
}
/**
* Hexbyte
*
* @param inHex
* @return
*/
static public byte hexToByte(String inHex)//
{
return (byte) Integer.parseInt(inHex, 16);
}
/**
* 1 2Hex
*
* @param inByte
* @return
*/
static public String byte2Hex(Byte inByte) {
return String.format("%02x", inByte).toUpperCase();
}
/**
* hex
*
* @param formatStr 1"%02x" 2"%04x"
* @param num
* @return
*/
static public String num2Hex(String formatStr, long num) {
return String.format(formatStr, num).toUpperCase();
}
/**
* hex
*
* @param inBytArr
* @return
*/
static public String byteArrToHex(byte[] inBytArr) {
StringBuilder strBuilder = new StringBuilder();
int j = inBytArr.length;
for (int i = 0; i < j; i++) {
strBuilder.append(byte2Hex(inBytArr[i]));
strBuilder.append(" ");
}
return strBuilder.toString();
}
/**
* hex
*
* @param inBytArr
* @param offset
* @param end
* @return
*/
static public String byteArrToHex(byte[] inBytArr, int offset, int end) {
StringBuilder strBuilder = new StringBuilder();
int j = end;
for (int i = offset; i < j; i++) {
strBuilder.append(byte2Hex(inBytArr[i]));
}
return strBuilder.toString();
}
/**
*
*
* @param inBytArr
* @param offset
* @param byteCount
* @return
*/
static public String byteArrToStr(byte[] inBytArr, int offset, int byteCount) {
byte[] array = new byte[byteCount - offset];
System.arraycopy(inBytArr, offset, array, 0, byteCount - offset);
return new String(array);
}
/**
* hex
*
* @param inHex
* @return
*/
static public byte[] hexToByteArr(String inHex)//hex字符串转字节数组
{
int hexlen = inHex.length();
byte[] result;
if (isOdd(hexlen) == 1) {//奇数
hexlen++;
result = new byte[(hexlen / 2)];
inHex = "0" + inHex;
} else {//偶数
result = new byte[(hexlen / 2)];
}
int j = 0;
for (int i = 0; i < hexlen; i += 2) {
result[j] = hexToByte(inHex.substring(i, i + 2));
j++;
}
return result;
}
/**
* 16
*
* @param inHex
* @return
*/
static public String reverseHexStr(String inHex) {
int hexlen = inHex.length();
StringBuilder stringBuilder = new StringBuilder();
for (int i = hexlen; i >= 2; i -= 2) {
stringBuilder.append(inHex.substring(i - 2, i));
}
return stringBuilder.toString();
}
}
Loading…
Cancel
Save