增加终端反馈

This commit is contained in:
2025-11-18 16:29:38 +08:00
parent f8eeb83c6f
commit 79d14ca300
4 changed files with 146 additions and 80 deletions
@@ -6,18 +6,14 @@ import android.graphics.Color
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.provider.Settings
import android.util.Log
import android.util.SparseArray
import android.util.SparseIntArray
import android.view.View
import androidx.activity.viewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.GridLayoutManager
import com.chad.library.adapter4.util.setOnDebouncedItemClick
import com.shuwei.intelligent.shelves.adapter.ShelfAdapter
import com.shuwei.intelligent.shelves.base.BaseActivity
import com.shuwei.intelligent.shelves.databinding.ActivityHomeBinding
@@ -33,7 +29,6 @@ import com.shuwei.intelligent.shelves.net.RespData
import com.shuwei.intelligent.shelves.net.UiState
import com.shuwei.intelligent.shelves.net.apiService
import com.shuwei.intelligent.shelves.serial.SerialPortManager
import com.shuwei.intelligent.shelves.task.SyncTask
import com.shuwei.intelligent.shelves.task.TaskManager
import com.shuwei.intelligent.shelves.utils.binaryToHex
import com.shuwei.intelligent.shelves.utils.ext.gone
@@ -43,9 +38,7 @@ import com.shuwei.intelligent.shelves.utils.ext.visible
import com.shuwei.intelligent.shelves.utils.f2C
import com.shuwei.intelligent.shelves.utils.hexToBinary
import com.shuwei.intelligent.shelves.utils.hexToDec
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
@@ -76,6 +69,7 @@ class HomeActivity : BaseActivity() {
//const val TEMPERATURE_CMD = "${HEADER}1001${FOOTER}"
const val DEVICE_INFO_CMD = "${HEADER}0301000000000000000000000000${FOOTER}"
//const val START_CMD= "${HEADER}0F01360000${FOOTER}"
//const val START_CMD= "${HEADER}0F01050020${FOOTER}"
const val ACTIVE_CMD =
@@ -115,22 +109,22 @@ class HomeActivity : BaseActivity() {
updateLeftStatus("-°C / -%")
initRecyclerView()
lifecycleScope.launch {
val openState = SerialPortManager.open()
Log.d(TAG, "onCreate: openState=$openState")
if (openState) {
SerialPortManager.startReceive { data ->
runOnUiThread {
// 更新UI显示接收数据
val openState = SerialPortManager.open()
Log.d(TAG, "onCreate: openState=$openState")
if (openState) {
SerialPortManager.startReceive { data ->
runOnUiThread {
// 更新UI显示接收数据
try {
receiveSerialPortData(data)
} catch (e: Exception) {
e.printStackTrace()
}
}
SerialPortManager.send(ACTIVE_CMD)
//SerialPortManager.send(DEVICE_INFO_CMD)
}
//SerialPortManager.send(DEVICE_INFO_CMD)
}
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.CREATED) {
launch {
viewModel.getAccessTokenUiState.collect { state ->
@@ -253,6 +247,16 @@ class HomeActivity : BaseActivity() {
loadEmptyView()
}
/**
* 终端id
*/
private var terminalId: String = ""
/**
* 固件版本
*/
private var terminalVersion: String = ""
private val serialReader by lazy { StringBuilder() }
private fun receiveSerialPortData(srcData: String) {
@@ -280,38 +284,86 @@ class HomeActivity : BaseActivity() {
val cmd = data.substring(HEADER.length, HEADER.length + 4)
when (cmd) {
"0001" -> {
//终端发起激活指令,拿到固定数据体(终端ID-15字节、固件版本-5字节、命令次数-1字节)
val reqBody = data.substring(HEADER.length + cmd.length, data.length - HEADER.length)
if (reqBody.length == 64) {
terminalId = reqBody.substring(2, 32)
terminalVersion = reqBody.substring(32, 42)
Log.d(TAG, "receiveSerialPortData:收到[激活]${cmd.substring(0,2)}指令:${data},终端id:${terminalId},固件版本:${terminalVersion},发送激活命令:${ACTIVE_CMD}")
SerialPortManager.send(ACTIVE_CMD)
} else {
runOnUiThread {
toast("收到终端激活指令错误")
}
SerialPortManager.send(ACTIVE_CMD)
}
}
"0101" -> {
//心跳-01
Log.d(TAG, "receiveSerialPortData:心跳01: $data")
"0101","8101" -> {
//心跳0102${p1}${p2}${version}
//心跳81(终端发起,当终端发送此命令时需要服务端存储串口屏显示信息)
val respCmd = "${HEADER}01020106${terminalVersion}${FOOTER}"
Log.d(TAG, "receiveSerialPortData:收到[心跳]${cmd.substring(0,2)}指令:${data},发送应答指令:${respCmd}")
SerialPortManager.send(respCmd)
heartBeat(data)
}
// "8101" -> {
// //心跳-81
// Log.d(TAG, "receiveSerialPortData:心跳08: $data")
// heartBeat(data)
// }
// "0202" -> {
// //开关锁反馈
// lockFeedback(data)
// }
"0202" -> {
//开关锁反馈020200${deviceId}${version}
val respCmd = "${HEADER}020200${terminalId}${terminalVersion}${FOOTER}"
Log.d(TAG, "receiveSerialPortData:收到[开锁]${cmd.substring(0,2)}指令:${data},发送应答指令:${respCmd}")
SerialPortManager.send(respCmd)
//lockFeedback(data)
}
"0302" -> {
//获取设备状态
getDeviceInfo(data)
}
"0501" -> {
//卡号上发
val respCmd = "${HEADER}050203${FOOTER}"
Log.d(TAG, "receiveSerialPortData:收到[卡号上发]${cmd.substring(0,2)}指令:${data},发送应答指令:${respCmd}")
SerialPortManager.send(respCmd)
}
"0B01" -> {
//操作记录上传
val respCmd = "${HEADER}0B0203${FOOTER}"
Log.d(TAG, "receiveSerialPortData:收到[操作记录上传]${cmd.substring(0,2)}指令:${data},发送应答指令:${respCmd}")
SerialPortManager.send(respCmd)
}
"0C01" -> {
//对时
val timeLong = System.currentTimeMillis() / 1000 + (8 * 3600)
val timeStr = "0000000" + String.format("%X", timeLong)
val time = timeStr.substring(timeStr.length - 8).chunked(2).reversed().joinToString("")
val respCmd = "${HEADER}0B02${time}${FOOTER}"
Log.d(TAG, "receiveSerialPortData:收到[对时]${cmd.substring(0,2)}指令:${data},发送应答指令:${respCmd}")
SerialPortManager.send(respCmd)
}
"0E01" -> {
//终端位置上报
val respCmd = "${HEADER}0E0200${FOOTER}"
Log.d(TAG, "receiveSerialPortData:收到[终端位置上报]${cmd.substring(0,2)}指令:${data},发送应答指令:${respCmd}")
SerialPortManager.send(respCmd)
}
"1001" -> {
Log.d(TAG, "receiveSerialPortData,温控信息上报数据:${data}")
runOnUiThread { toast("温控信息上报数据:${data}") }
}
"1002" -> {
Log.d(TAG, "receiveSerialPortData,温控信息上报1002数据:${data}")
}
"0F02" -> {
Log.d(TAG, "receiveSerialPortData,温控信息应答数据:${data}")
//温控信息上报
val respCmd = "${HEADER}100200${FOOTER}"
Log.d(TAG, "receiveSerialPortData:收到[温控信息上报]${cmd.substring(0,2)}指令:${data},发送应答指令:${respCmd}")
SerialPortManager.send(respCmd)
}
//"1002" -> {
// Log.d(TAG, "receiveSerialPortData,温控信息上报1002数据:${data}")
//}
//"0F02" -> {
// Log.d(TAG, "receiveSerialPortData,温控信息应答数据:${data}")
//}
else -> {}
}
}
@@ -328,16 +380,12 @@ class HomeActivity : BaseActivity() {
val lockOneState = data.substring(HEADER.length + 4, HEADER.length + 6)
if (lockOneState == "00") {
//锁1关
lifecycleScope.launch {
SerialPortManager.send("${HEADER}0202${lockNo}${FOOTER}")
}
SerialPortManager.send("${HEADER}0202${lockNo}${FOOTER}")
}
val lockTwoState = data.substring(HEADER.length + 6, HEADER.length + 8)
if (lockTwoState == "00") {
//锁2关
lifecycleScope.launch {
SerialPortManager.send("${HEADER}0202${lockNo}${FOOTER}")
}
SerialPortManager.send("${HEADER}0202${lockNo}${FOOTER}")
}
}.onFailure {
it.printStackTrace()
@@ -442,6 +490,20 @@ class HomeActivity : BaseActivity() {
end = temperatureStartIndex,
data = data
)
if (terminalId.isBlank() || terminalVersion.isBlank()) {
try {
val fixDataBodyStartIndex = temperatureEndIndex + 1
val fixDataBody = data.substring(fixDataBodyStartIndex)
if (fixDataBody.length == 62) {
terminalId = fixDataBody.substring(0, 30)
terminalVersion = fixDataBody.substring(30, 40)
Log.d(TAG, "receiveSerialPortData:从设备状态获取数据,终端id:${terminalId},固件版本:${terminalVersion}")
}
} catch (e: Exception) {
e.printStackTrace()
}
}
}
override fun onDestroy() {
@@ -487,7 +549,7 @@ class HomeActivity : BaseActivity() {
try {
val submitList = list.sortedBy { item-> item.deviceNo }
val submitList = list.sortedBy { item -> item.deviceNo }
val body = ShelfBody().also { body ->
body.deviceId = App.deviceId ?: ""
body.canteenId = App.canteenId
@@ -577,7 +639,7 @@ class HomeActivity : BaseActivity() {
goodsId = ""
goodsName = null
weight = 0.0
weightBak = if (event.weight <= 0.0 ) 0.0 else -1 * event.weight.toDouble()
weightBak = if (event.weight <= 0.0) 0.0 else -1 * event.weight.toDouble()
createTime = null
overdueDay = null
}
@@ -84,7 +84,7 @@ open class BaseActivity : AppCompatActivity() {
}
fun setBackground() {
binding.root.setBackgroundColor(ContextCompat.getColor(this,R.color.bg_page))
binding.root.setBackgroundColor(ContextCompat.getColor(this, R.color.bg_page))
}
override fun setContentView(view: View?) {
@@ -115,7 +115,7 @@ open class BaseActivity : AppCompatActivity() {
override fun onUserInteraction() {
super.onUserInteraction()
//开灯
if(System.currentTimeMillis() - lastTouchTime >= TIME_OUT) {
if (System.currentTimeMillis() - lastTouchTime >= TIME_OUT) {
this.switchLight(true)
}
// 重置定时器
@@ -140,12 +140,10 @@ open class BaseActivity : AppCompatActivity() {
fun switchLight(isOpen: Boolean) {
val tag = binding.tvLeftStatus.tag?.toString()?.toBoolean() ?: true
if(tag == isOpen) {
if (tag == isOpen) {
return
}
lifecycleScope.launch {
SerialPortManager.send(if (isOpen) LIGHT_OPEN else LIGHT_CLOSE)
}
SerialPortManager.send(if (isOpen) LIGHT_OPEN else LIGHT_CLOSE)
binding.tvLeftStatus.tag = isOpen
}
@@ -156,7 +154,7 @@ open class BaseActivity : AppCompatActivity() {
switchLight(tag.not())
}
binding.tvRightStatus.clickWithDebounce {
startActivity<SettingActivity> { }
startActivity<SettingActivity> { }
}
}
@@ -1,6 +1,7 @@
package com.shuwei.intelligent.shelves.serial
import android.annotation.SuppressLint
import androidx.lifecycle.lifecycleScope
import com.shuwei.intelligent.shelves.utils.hexToBytes
import com.shuwei.intelligent.shelves.utils.toHexString2
import io.github.jeadyx.jserialport.AndroidSerialPort
@@ -14,37 +15,42 @@ import java.util.Locale
object SerialPortManager {
private const val portName: String = "/dev/ttyS1"
private const val baudRate: Int = 115200
private var serialPort: AndroidSerialPort? = null
// private var serialPort: SerialPort? = null
private var serialPort: AndroidSerialPort? = null
// private var serialPort: SerialPort? = null
private val scope = CoroutineScope(Dispatchers.IO)
// 打开串口
suspend fun open(): Boolean {
return try {
serialPort = SerialPortFactory.create().apply {
open(
portName = portName,
baudRate = baudRate,
dataBits = 8,
stopBits = 1,
parity = SerialPort.PARITY_NONE
)
} as AndroidSerialPort?
true
} catch (e: Exception) {
e.printStackTrace()
false
fun open(): Boolean {
lifecycleScope.launch {
return try {
serialPort = SerialPortFactory.create().apply {
open(
portName = portName,
baudRate = baudRate,
dataBits = 8,
stopBits = 1,
parity = SerialPort.PARITY_NONE
)
} as AndroidSerialPort?
true
} catch (e: Exception) {
e.printStackTrace()
false
}
}
}
// 发送数据
suspend fun send(data: String): Boolean {
return try {
serialPort?.write(data.hexToBytes())
true
} catch (e: Exception) {
e.printStackTrace()
false
fun send(data: String): Boolean {
lifecycleScope.launch {
return try {
serialPort?.write(data.hexToBytes())
true
} catch (e: Exception) {
e.printStackTrace()
false
}
}
}
@@ -14,7 +14,7 @@ class SyncDeviceTask(appContext: Context, workerParams: WorkerParameters) :
private const val TAG = "SyncDeviceTask"
}
override suspend fun doWork(): Result {
override fun doWork(): Result {
return try {
// 执行后台任务逻辑
Log.d(TAG, "doWork: ----------SyncDeviceTask----------")