From 79d14ca300c9c91fb2291e0de4e90e41705221c5 Mon Sep 17 00:00:00 2001 From: lvmeng <848755140@qq.com> Date: Tue, 18 Nov 2025 16:29:38 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=BB=88=E7=AB=AF=E5=8F=8D?= =?UTF-8?q?=E9=A6=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../intelligent/shelves/HomeActivity.kt | 158 ++++++++++++------ .../intelligent/shelves/base/BaseActivity.kt | 12 +- .../shelves/serial/SerialPortManager.kt | 54 +++--- .../shelves/task/SyncDeviceTask.kt | 2 +- 4 files changed, 146 insertions(+), 80 deletions(-) diff --git a/app/src/main/java/com/shuwei/intelligent/shelves/HomeActivity.kt b/app/src/main/java/com/shuwei/intelligent/shelves/HomeActivity.kt index 38d563d..9cf858e 100644 --- a/app/src/main/java/com/shuwei/intelligent/shelves/HomeActivity.kt +++ b/app/src/main/java/com/shuwei/intelligent/shelves/HomeActivity.kt @@ -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 } diff --git a/app/src/main/java/com/shuwei/intelligent/shelves/base/BaseActivity.kt b/app/src/main/java/com/shuwei/intelligent/shelves/base/BaseActivity.kt index fff4e2c..20e98f0 100644 --- a/app/src/main/java/com/shuwei/intelligent/shelves/base/BaseActivity.kt +++ b/app/src/main/java/com/shuwei/intelligent/shelves/base/BaseActivity.kt @@ -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 { } + startActivity { } } } diff --git a/app/src/main/java/com/shuwei/intelligent/shelves/serial/SerialPortManager.kt b/app/src/main/java/com/shuwei/intelligent/shelves/serial/SerialPortManager.kt index 7fce0e8..fca55e4 100644 --- a/app/src/main/java/com/shuwei/intelligent/shelves/serial/SerialPortManager.kt +++ b/app/src/main/java/com/shuwei/intelligent/shelves/serial/SerialPortManager.kt @@ -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 + } } } diff --git a/app/src/main/java/com/shuwei/intelligent/shelves/task/SyncDeviceTask.kt b/app/src/main/java/com/shuwei/intelligent/shelves/task/SyncDeviceTask.kt index 417dba6..0989cde 100644 --- a/app/src/main/java/com/shuwei/intelligent/shelves/task/SyncDeviceTask.kt +++ b/app/src/main/java/com/shuwei/intelligent/shelves/task/SyncDeviceTask.kt @@ -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----------")