From 926bb54a18d4f0c1db6b092960d87b99597eeec0 Mon Sep 17 00:00:00 2001 From: xiaowusky Date: Wed, 6 Sep 2023 15:33:51 +0800 Subject: [PATCH] =?UTF-8?q?desc:=E8=A7=A3=E6=9E=90=E4=BC=A0=E6=84=9F?= =?UTF-8?q?=E5=99=A8=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 25 +++ .../java/com/yinuo/safetywatcher/TestUtils.kt | 12 -- .../com/yinuo/safetywatcher/watcher/App.kt | 6 +- .../safetywatcher/watcher/port/GasUtils.kt | 107 ++++--------- .../safetywatcher/watcher/port/ParseHelper.kt | 144 +++++++++++++++++ .../safetywatcher/watcher/port/cmd/CMD.kt | 10 ++ .../safetywatcher/watcher/port/cmd/CRC.kt | 50 ++++++ .../watcher/port/cmd/GasAddress.kt | 18 +++ .../watcher/port/cmd/GasPortStatus.kt | 19 +++ .../safetywatcher/watcher/port/cmd/GasType.kt | 19 +++ .../watcher/port/cmd/ResponseHelper.kt | 30 ++++ .../watcher/ui/adapter/SensorAdapter.kt | 23 ++- app/src/main/res/values/colors.xml | 1 + app/src/main/res/values/strings.xml | 1 + buildCommon/commonLibConfig.gradle | 2 +- innovationapp.jks | Bin 0 -> 2469 bytes .../com/common/commonlib/db/entity/GasType.kt | 3 +- .../com/common/serialport/EasySerialPort.kt | 56 ++++--- .../common/serialport/utils/DataUtils.java | 139 ----------------- .../com/common/serialport/utils/HexUtils.java | 146 ++++++++++++++++++ 20 files changed, 550 insertions(+), 261 deletions(-) create mode 100644 app/src/main/java/com/yinuo/safetywatcher/watcher/port/ParseHelper.kt create mode 100644 app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/CMD.kt create mode 100644 app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/CRC.kt create mode 100644 app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/GasAddress.kt create mode 100644 app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/GasPortStatus.kt create mode 100644 app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/GasType.kt create mode 100644 app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/ResponseHelper.kt create mode 100644 innovationapp.jks delete mode 100644 library-serialPort/src/main/java/com/common/serialport/utils/DataUtils.java create mode 100644 library-serialPort/src/main/java/com/common/serialport/utils/HexUtils.java diff --git a/app/build.gradle b/app/build.gradle index 7f379c8..d862be0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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' } diff --git a/app/src/main/java/com/yinuo/safetywatcher/TestUtils.kt b/app/src/main/java/com/yinuo/safetywatcher/TestUtils.kt index 9e0ecd7..ab987f5 100644 --- a/app/src/main/java/com/yinuo/safetywatcher/TestUtils.kt +++ b/app/src/main/java/com/yinuo/safetywatcher/TestUtils.kt @@ -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() - list.add(GasType("CO", "", false)) - list.add(GasType("CO2", "", false)) - list.add(GasType("O2", "", false)) - typeDao.insertAll(list) - // 构造气体数据 val timeMillis = System.currentTimeMillis() diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/App.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/App.kt index 89e287b..7b5b4a0 100644 --- a/app/src/main/java/com/yinuo/safetywatcher/watcher/App.kt +++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/App.kt @@ -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() diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/port/GasUtils.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/port/GasUtils.kt index 0ca418d..5715232 100644 --- a/app/src/main/java/com/yinuo/safetywatcher/watcher/port/GasUtils.kt +++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/port/GasUtils.kt @@ -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() - 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) - } - } } \ No newline at end of file diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/port/ParseHelper.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/port/ParseHelper.kt new file mode 100644 index 0000000..9d39e78 --- /dev/null +++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/port/ParseHelper.kt @@ -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() + 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) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/CMD.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/CMD.kt new file mode 100644 index 0000000..06f517d --- /dev/null +++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/CMD.kt @@ -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() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/CRC.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/CRC.kt new file mode 100644 index 0000000..664ad40 --- /dev/null +++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/CRC.kt @@ -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] +} diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/GasAddress.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/GasAddress.kt new file mode 100644 index 0000000..8a043c9 --- /dev/null +++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/GasAddress.kt @@ -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 + } +} diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/GasPortStatus.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/GasPortStatus.kt new file mode 100644 index 0000000..3e7fd8b --- /dev/null +++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/GasPortStatus.kt @@ -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 + } +} diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/GasType.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/GasType.kt new file mode 100644 index 0000000..48d8c29 --- /dev/null +++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/GasType.kt @@ -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 "" +} diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/ResponseHelper.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/ResponseHelper.kt new file mode 100644 index 0000000..846e519 --- /dev/null +++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/ResponseHelper.kt @@ -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 -> "" + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/adapter/SensorAdapter.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/adapter/SensorAdapter.kt index 83fcca3..d73b252 100644 --- a/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/adapter/SensorAdapter.kt +++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/adapter/SensorAdapter.kt @@ -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 + } } } } diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 63095ab..537d65a 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -21,6 +21,7 @@ #202A45 #01E41C + #f6d365 #999999 #E40101 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 07cf0e2..a30fb8d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -31,6 +31,7 @@ 正常 离线 + 预热 故障 传感器报警值设定 保存 diff --git a/buildCommon/commonLibConfig.gradle b/buildCommon/commonLibConfig.gradle index 5ab29a3..4ef5b2a 100644 --- a/buildCommon/commonLibConfig.gradle +++ b/buildCommon/commonLibConfig.gradle @@ -1,6 +1,6 @@ project.ext { sign = [ - keystore_path : "../signature/innovationapp.jks", + keystore_path : "../innovationapp.jks", keystore_pwd : "123456", keystore_alias: "yinuo" ] diff --git a/innovationapp.jks b/innovationapp.jks new file mode 100644 index 0000000000000000000000000000000000000000..20f47af44008d7917ea92859b81b9e0190351a0b GIT binary patch literal 2469 zcmY+EXH*gj8^;k4MI7Z;w6taQecC)Q1nG3!&HU zS@(UD{z-)@b^gX5F9pB|c$EZ^^PhS2hUYsADEMhWIBO-M=OVB@9k=UXk}zSP*GYJI zUq^3+Gkw3eXdAy*n}P2pmIR_Ae$;mcF5IpE^5h!Xa}0bF<9EnZ@B-U6_M4T5^tG83 z+O-HW&vE8Ds)kNA1r`|F&GMLm&E2v6ZO1_=*vA%Ms6d>8cWS~b zp7^xZYJSrZ*BiJ=*M^*7);+G3z^+qcT*_k(GJy?+Z!S8YeIrH_n^zfkSvtCP>)T-S zD(*NszyYo(je^B#J?}M;^c5-{?N@K_eMLE&)eb$4NzuoYQYqo(5=x3MJ;lVWXakBQ zPzW{jY@SKfQ9^Os`KQGz1~HJ41kKoYOJ|}OYdsB7zf^-?p$Fq42Uxv_KCIydAqkGH+5g!O3K<$)!2U{ZmFi5c5Ia#v-rSTsQ__uO&&nbPIWcH>)LzOtqD?|xq?A65Rt z$=ek74jou`3Gwc;uPF*6yp(O|tyd{=3s#jY`8D~o{8OyaG-c+_)h4ewMKl(aU* zsTuN#Z;;oZ3@M1!fgGB0f(DCRwXtT(qMoDmOdyqNIfR|cGQ~IvG1MgAPYpp-tC4QJ zoBLYgkYcB~A`Uev15D&IT*Q~(K9~$S$YP$}Nu0tw4Mr=RaHmZyx$3VSwVB$U*)uzS z`=gp7?-5(pLa*Dpb8+eMm`@6jggsrWdU?0`bd45XOyqFF<2;2I2}Ae1gq%w~oi@Bt z>66>)>?5mrbMCQ2bGYhHw$D>lPuK>^f@_SLp7xsk2!XMb?jWZh-ni`Q35fH5r7s@( zRjRxD%ID*>*F-cdz!W-U57QNmY0S<+GV*WYo6wBxa$qjTvTFin7DVye!OEw2^lD$W zM;am|{#GSa7|DB#2S5P$1400ifKY_&KamJh7%b@EAM7oI)X~&I=%A3g+Io5j1PL_y zcZmy9O#;38g?fP;fM2WQpM>LIeuezUukfnsYbA>ZUj}8|bR={*e|}$48T+qalSrVX zrtLlX8THU29`Ct!CB+O?ImrD?kz&JB+1mN#^Z_glP@|Td-DB%DlYoCg^__mh7;D8l z$#+ko?#g6kq>Hn3)L*i@ca785R(5%bCHC#x3^zH8so)WgVpiDw0P^s+_nYaCAZk3d zT1yQXL=GPM*%^e_qKRgE)NqwXNEdW#s6IGyallf0d^0gr__Py7j-Tt0=lXhhqt0vl zCE{1<-w24+(X3@|SNhL{wquUkDbvQ&x+uxxS1F(yema-nw4z=?80@Vvo$0UFU` zkxh7eP6$SM#sxJYv$TBV_v!N`mRG2@R6XN)P_$sngqIDoL-g~><(l#9rSPh)!@!%2 zn4C}KHU(9O=8xJl1|I3X2L}XfF=8qTL-}!pqGO@nQfqkj@RZPriHK%tE9L`F{l1Dh zwvj?{ebN28AnTdkSpiuIfok0;%N6&THs(~`JDe}hlalqWG2cXA)*FGm|pU8aL)!R}cK)9XgqZ8c8yL%<6lkeqI895^zPt7>7(^twj8(h|{CK zUB-sugFj2eVbYlzN%FV(l-w9KWfhv2Wj>B;CuXiOF0(%)we+4z&p2l@POYMfU&s>CINZRw z{nf%MHPj%Pol7=}E^Z~Hm<&sAj3mjlvQkJb7Yl)+lfbexe70d&*|YZo9c3=23f8}? z=3qgOz(Xv(B8banb=VCfz6CcG#RBEnTIJamP!Ie-E$WbN%UBHyDe&Veui1o)g~IF$>cd_^ z1Y;TbanbZS!G<26o@jrioi45mg$*umEFBg2D|3zLJc{G}6H_uRTBH+KTAq@HoG-h_ zXJuxKl81Wg9_J2kttUMnp-WwHk6xh@gD{06 zgy=VI>xS!>5QYd@1Qf!l!VdyUast4@dXW@9>DZkv`clS^JVH0ZqGE&_Ec~!x6MaE8 XDN8kcpz0Jcl!DYZ^8$i6(yRXhI52%e literal 0 HcmV?d00001 diff --git a/library-common/src/main/java/com/common/commonlib/db/entity/GasType.kt b/library-common/src/main/java/com/common/commonlib/db/entity/GasType.kt index b95d07a..2266947 100644 --- a/library-common/src/main/java/com/common/commonlib/db/entity/GasType.kt +++ b/library-common/src/main/java/com/common/commonlib/db/entity/GasType.kt @@ -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, ) diff --git a/library-serialPort/src/main/java/com/common/serialport/EasySerialPort.kt b/library-serialPort/src/main/java/com/common/serialport/EasySerialPort.kt index f4cb2da..92c6830 100644 --- a/library-serialPort/src/main/java/com/common/serialport/EasySerialPort.kt +++ b/library-serialPort/src/main/java/com/common/serialport/EasySerialPort.kt @@ -42,13 +42,14 @@ class EasySerialPort( 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( * 写消息 */ 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() } /** diff --git a/library-serialPort/src/main/java/com/common/serialport/utils/DataUtils.java b/library-serialPort/src/main/java/com/common/serialport/utils/DataUtils.java deleted file mode 100644 index a5d45bd..0000000 --- a/library-serialPort/src/main/java/com/common/serialport/utils/DataUtils.java +++ /dev/null @@ -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 getDivLines(String inputString, int length) { - List 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 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(); - } -} diff --git a/library-serialPort/src/main/java/com/common/serialport/utils/HexUtils.java b/library-serialPort/src/main/java/com/common/serialport/utils/HexUtils.java new file mode 100644 index 0000000..e1aab3a --- /dev/null +++ b/library-serialPort/src/main/java/com/common/serialport/utils/HexUtils.java @@ -0,0 +1,146 @@ +package com.common.serialport.utils; + +/** + * 数据转换工具 + */ +public class HexUtils { + /** + * 判断奇数或偶数,位运算,最后一位是1则为奇数,为0是偶数 + * + * @param num + * @return + */ + static public int isOdd(int num) { + return num & 0x1; + } + + /** + * Hex字符串转Long + * + * @param inHex + * @return + */ + static public long hexToLong(String inHex) { + return Long.parseLong(inHex, 16); + } + + /** + * Hex字符串转byte + * + * @param inHex + * @return + */ + static public byte hexToByte(String inHex)// + { + return (byte) Integer.parseInt(inHex, 16); + } + + /** + * 1字节转 2个Hex字符 + * + * @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(); + } +} \ No newline at end of file