增加终端反馈
This commit is contained in:
@@ -6,18 +6,14 @@ import android.graphics.Color
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.provider.Settings
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.util.SparseArray
|
|
||||||
import android.util.SparseIntArray
|
import android.util.SparseIntArray
|
||||||
import android.view.View
|
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.lifecycle.Lifecycle
|
import androidx.lifecycle.Lifecycle
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.lifecycle.repeatOnLifecycle
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
import androidx.recyclerview.widget.DefaultItemAnimator
|
import androidx.recyclerview.widget.DefaultItemAnimator
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
import com.chad.library.adapter4.util.setOnDebouncedItemClick
|
|
||||||
import com.shuwei.intelligent.shelves.adapter.ShelfAdapter
|
import com.shuwei.intelligent.shelves.adapter.ShelfAdapter
|
||||||
import com.shuwei.intelligent.shelves.base.BaseActivity
|
import com.shuwei.intelligent.shelves.base.BaseActivity
|
||||||
import com.shuwei.intelligent.shelves.databinding.ActivityHomeBinding
|
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.UiState
|
||||||
import com.shuwei.intelligent.shelves.net.apiService
|
import com.shuwei.intelligent.shelves.net.apiService
|
||||||
import com.shuwei.intelligent.shelves.serial.SerialPortManager
|
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.task.TaskManager
|
||||||
import com.shuwei.intelligent.shelves.utils.binaryToHex
|
import com.shuwei.intelligent.shelves.utils.binaryToHex
|
||||||
import com.shuwei.intelligent.shelves.utils.ext.gone
|
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.f2C
|
||||||
import com.shuwei.intelligent.shelves.utils.hexToBinary
|
import com.shuwei.intelligent.shelves.utils.hexToBinary
|
||||||
import com.shuwei.intelligent.shelves.utils.hexToDec
|
import com.shuwei.intelligent.shelves.utils.hexToDec
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
import org.greenrobot.eventbus.Subscribe
|
import org.greenrobot.eventbus.Subscribe
|
||||||
import org.greenrobot.eventbus.ThreadMode
|
import org.greenrobot.eventbus.ThreadMode
|
||||||
@@ -76,6 +69,7 @@ class HomeActivity : BaseActivity() {
|
|||||||
//const val TEMPERATURE_CMD = "${HEADER}1001${FOOTER}"
|
//const val TEMPERATURE_CMD = "${HEADER}1001${FOOTER}"
|
||||||
|
|
||||||
const val DEVICE_INFO_CMD = "${HEADER}0301000000000000000000000000${FOOTER}"
|
const val DEVICE_INFO_CMD = "${HEADER}0301000000000000000000000000${FOOTER}"
|
||||||
|
|
||||||
//const val START_CMD= "${HEADER}0F01360000${FOOTER}"
|
//const val START_CMD= "${HEADER}0F01360000${FOOTER}"
|
||||||
//const val START_CMD= "${HEADER}0F01050020${FOOTER}"
|
//const val START_CMD= "${HEADER}0F01050020${FOOTER}"
|
||||||
const val ACTIVE_CMD =
|
const val ACTIVE_CMD =
|
||||||
@@ -115,22 +109,22 @@ class HomeActivity : BaseActivity() {
|
|||||||
updateLeftStatus("-°C / -%")
|
updateLeftStatus("-°C / -%")
|
||||||
|
|
||||||
initRecyclerView()
|
initRecyclerView()
|
||||||
|
val openState = SerialPortManager.open()
|
||||||
lifecycleScope.launch {
|
Log.d(TAG, "onCreate: openState=$openState")
|
||||||
val openState = SerialPortManager.open()
|
if (openState) {
|
||||||
Log.d(TAG, "onCreate: openState=$openState")
|
SerialPortManager.startReceive { data ->
|
||||||
if (openState) {
|
runOnUiThread {
|
||||||
SerialPortManager.startReceive { data ->
|
// 更新UI显示接收数据
|
||||||
runOnUiThread {
|
try {
|
||||||
// 更新UI显示接收数据
|
|
||||||
receiveSerialPortData(data)
|
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) {
|
repeatOnLifecycle(Lifecycle.State.CREATED) {
|
||||||
launch {
|
launch {
|
||||||
viewModel.getAccessTokenUiState.collect { state ->
|
viewModel.getAccessTokenUiState.collect { state ->
|
||||||
@@ -253,6 +247,16 @@ class HomeActivity : BaseActivity() {
|
|||||||
loadEmptyView()
|
loadEmptyView()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 终端id
|
||||||
|
*/
|
||||||
|
private var terminalId: String = ""
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 固件版本
|
||||||
|
*/
|
||||||
|
private var terminalVersion: String = ""
|
||||||
|
|
||||||
private val serialReader by lazy { StringBuilder() }
|
private val serialReader by lazy { StringBuilder() }
|
||||||
|
|
||||||
private fun receiveSerialPortData(srcData: String) {
|
private fun receiveSerialPortData(srcData: String) {
|
||||||
@@ -280,38 +284,86 @@ class HomeActivity : BaseActivity() {
|
|||||||
val cmd = data.substring(HEADER.length, HEADER.length + 4)
|
val cmd = data.substring(HEADER.length, HEADER.length + 4)
|
||||||
when (cmd) {
|
when (cmd) {
|
||||||
"0001" -> {
|
"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" -> {
|
"0101","8101" -> {
|
||||||
//心跳-01
|
//心跳0102${p1}${p2}${version}
|
||||||
Log.d(TAG, "receiveSerialPortData:心跳01: $data")
|
//心跳81(终端发起,当终端发送此命令时需要服务端存储串口屏显示信息)
|
||||||
|
val respCmd = "${HEADER}01020106${terminalVersion}${FOOTER}"
|
||||||
|
Log.d(TAG, "receiveSerialPortData:收到[心跳]${cmd.substring(0,2)}指令:${data},发送应答指令:${respCmd}")
|
||||||
|
SerialPortManager.send(respCmd)
|
||||||
heartBeat(data)
|
heartBeat(data)
|
||||||
}
|
}
|
||||||
// "8101" -> {
|
|
||||||
// //心跳-81
|
"0202" -> {
|
||||||
// Log.d(TAG, "receiveSerialPortData:心跳08: $data")
|
//开关锁反馈020200${deviceId}${version}
|
||||||
// heartBeat(data)
|
val respCmd = "${HEADER}020200${terminalId}${terminalVersion}${FOOTER}"
|
||||||
// }
|
Log.d(TAG, "receiveSerialPortData:收到[开锁]${cmd.substring(0,2)}指令:${data},发送应答指令:${respCmd}")
|
||||||
// "0202" -> {
|
SerialPortManager.send(respCmd)
|
||||||
// //开关锁反馈
|
//lockFeedback(data)
|
||||||
// lockFeedback(data)
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
"0302" -> {
|
"0302" -> {
|
||||||
//获取设备状态
|
//获取设备状态
|
||||||
getDeviceInfo(data)
|
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" -> {
|
"1001" -> {
|
||||||
Log.d(TAG, "receiveSerialPortData,温控信息上报数据:${data}")
|
//温控信息上报
|
||||||
runOnUiThread { toast("温控信息上报数据:${data}") }
|
val respCmd = "${HEADER}100200${FOOTER}"
|
||||||
}
|
Log.d(TAG, "receiveSerialPortData:收到[温控信息上报]${cmd.substring(0,2)}指令:${data},发送应答指令:${respCmd}")
|
||||||
"1002" -> {
|
SerialPortManager.send(respCmd)
|
||||||
Log.d(TAG, "receiveSerialPortData,温控信息上报1002数据:${data}")
|
|
||||||
}
|
|
||||||
"0F02" -> {
|
|
||||||
Log.d(TAG, "receiveSerialPortData,温控信息应答数据:${data}")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//"1002" -> {
|
||||||
|
// Log.d(TAG, "receiveSerialPortData,温控信息上报1002数据:${data}")
|
||||||
|
//}
|
||||||
|
//"0F02" -> {
|
||||||
|
// Log.d(TAG, "receiveSerialPortData,温控信息应答数据:${data}")
|
||||||
|
//}
|
||||||
|
|
||||||
else -> {}
|
else -> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -328,16 +380,12 @@ class HomeActivity : BaseActivity() {
|
|||||||
val lockOneState = data.substring(HEADER.length + 4, HEADER.length + 6)
|
val lockOneState = data.substring(HEADER.length + 4, HEADER.length + 6)
|
||||||
if (lockOneState == "00") {
|
if (lockOneState == "00") {
|
||||||
//锁1关
|
//锁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)
|
val lockTwoState = data.substring(HEADER.length + 6, HEADER.length + 8)
|
||||||
if (lockTwoState == "00") {
|
if (lockTwoState == "00") {
|
||||||
//锁2关
|
//锁2关
|
||||||
lifecycleScope.launch {
|
SerialPortManager.send("${HEADER}0202${lockNo}${FOOTER}")
|
||||||
SerialPortManager.send("${HEADER}0202${lockNo}${FOOTER}")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}.onFailure {
|
}.onFailure {
|
||||||
it.printStackTrace()
|
it.printStackTrace()
|
||||||
@@ -442,6 +490,20 @@ class HomeActivity : BaseActivity() {
|
|||||||
end = temperatureStartIndex,
|
end = temperatureStartIndex,
|
||||||
data = data
|
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() {
|
override fun onDestroy() {
|
||||||
@@ -487,7 +549,7 @@ class HomeActivity : BaseActivity() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
val submitList = list.sortedBy { item-> item.deviceNo }
|
val submitList = list.sortedBy { item -> item.deviceNo }
|
||||||
val body = ShelfBody().also { body ->
|
val body = ShelfBody().also { body ->
|
||||||
body.deviceId = App.deviceId ?: ""
|
body.deviceId = App.deviceId ?: ""
|
||||||
body.canteenId = App.canteenId
|
body.canteenId = App.canteenId
|
||||||
@@ -577,7 +639,7 @@ class HomeActivity : BaseActivity() {
|
|||||||
goodsId = ""
|
goodsId = ""
|
||||||
goodsName = null
|
goodsName = null
|
||||||
weight = 0.0
|
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
|
createTime = null
|
||||||
overdueDay = null
|
overdueDay = null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ open class BaseActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun setBackground() {
|
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?) {
|
override fun setContentView(view: View?) {
|
||||||
@@ -115,7 +115,7 @@ open class BaseActivity : AppCompatActivity() {
|
|||||||
override fun onUserInteraction() {
|
override fun onUserInteraction() {
|
||||||
super.onUserInteraction()
|
super.onUserInteraction()
|
||||||
//开灯
|
//开灯
|
||||||
if(System.currentTimeMillis() - lastTouchTime >= TIME_OUT) {
|
if (System.currentTimeMillis() - lastTouchTime >= TIME_OUT) {
|
||||||
this.switchLight(true)
|
this.switchLight(true)
|
||||||
}
|
}
|
||||||
// 重置定时器
|
// 重置定时器
|
||||||
@@ -140,12 +140,10 @@ open class BaseActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
fun switchLight(isOpen: Boolean) {
|
fun switchLight(isOpen: Boolean) {
|
||||||
val tag = binding.tvLeftStatus.tag?.toString()?.toBoolean() ?: true
|
val tag = binding.tvLeftStatus.tag?.toString()?.toBoolean() ?: true
|
||||||
if(tag == isOpen) {
|
if (tag == isOpen) {
|
||||||
return
|
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
|
binding.tvLeftStatus.tag = isOpen
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,7 +154,7 @@ open class BaseActivity : AppCompatActivity() {
|
|||||||
switchLight(tag.not())
|
switchLight(tag.not())
|
||||||
}
|
}
|
||||||
binding.tvRightStatus.clickWithDebounce {
|
binding.tvRightStatus.clickWithDebounce {
|
||||||
startActivity<SettingActivity> { }
|
startActivity<SettingActivity> { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.shuwei.intelligent.shelves.serial
|
package com.shuwei.intelligent.shelves.serial
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.shuwei.intelligent.shelves.utils.hexToBytes
|
import com.shuwei.intelligent.shelves.utils.hexToBytes
|
||||||
import com.shuwei.intelligent.shelves.utils.toHexString2
|
import com.shuwei.intelligent.shelves.utils.toHexString2
|
||||||
import io.github.jeadyx.jserialport.AndroidSerialPort
|
import io.github.jeadyx.jserialport.AndroidSerialPort
|
||||||
@@ -14,37 +15,42 @@ import java.util.Locale
|
|||||||
object SerialPortManager {
|
object SerialPortManager {
|
||||||
private const val portName: String = "/dev/ttyS1"
|
private const val portName: String = "/dev/ttyS1"
|
||||||
private const val baudRate: Int = 115200
|
private const val baudRate: Int = 115200
|
||||||
private var serialPort: AndroidSerialPort? = null
|
private var serialPort: AndroidSerialPort? = null
|
||||||
// private var serialPort: SerialPort? = null
|
|
||||||
|
// private var serialPort: SerialPort? = null
|
||||||
private val scope = CoroutineScope(Dispatchers.IO)
|
private val scope = CoroutineScope(Dispatchers.IO)
|
||||||
|
|
||||||
// 打开串口
|
// 打开串口
|
||||||
suspend fun open(): Boolean {
|
fun open(): Boolean {
|
||||||
return try {
|
lifecycleScope.launch {
|
||||||
serialPort = SerialPortFactory.create().apply {
|
return try {
|
||||||
open(
|
serialPort = SerialPortFactory.create().apply {
|
||||||
portName = portName,
|
open(
|
||||||
baudRate = baudRate,
|
portName = portName,
|
||||||
dataBits = 8,
|
baudRate = baudRate,
|
||||||
stopBits = 1,
|
dataBits = 8,
|
||||||
parity = SerialPort.PARITY_NONE
|
stopBits = 1,
|
||||||
)
|
parity = SerialPort.PARITY_NONE
|
||||||
} as AndroidSerialPort?
|
)
|
||||||
true
|
} as AndroidSerialPort?
|
||||||
} catch (e: Exception) {
|
true
|
||||||
e.printStackTrace()
|
} catch (e: Exception) {
|
||||||
false
|
e.printStackTrace()
|
||||||
|
false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 发送数据
|
// 发送数据
|
||||||
suspend fun send(data: String): Boolean {
|
fun send(data: String): Boolean {
|
||||||
return try {
|
lifecycleScope.launch {
|
||||||
serialPort?.write(data.hexToBytes())
|
return try {
|
||||||
true
|
serialPort?.write(data.hexToBytes())
|
||||||
} catch (e: Exception) {
|
true
|
||||||
e.printStackTrace()
|
} catch (e: Exception) {
|
||||||
false
|
e.printStackTrace()
|
||||||
|
false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class SyncDeviceTask(appContext: Context, workerParams: WorkerParameters) :
|
|||||||
private const val TAG = "SyncDeviceTask"
|
private const val TAG = "SyncDeviceTask"
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun doWork(): Result {
|
override fun doWork(): Result {
|
||||||
return try {
|
return try {
|
||||||
// 执行后台任务逻辑
|
// 执行后台任务逻辑
|
||||||
Log.d(TAG, "doWork: ----------SyncDeviceTask----------")
|
Log.d(TAG, "doWork: ----------SyncDeviceTask----------")
|
||||||
|
|||||||
Reference in New Issue
Block a user