package com.shuwei.intelligent.shelves import android.annotation.SuppressLint import android.content.Intent import android.os.Bundle import android.os.Handler import android.os.Looper import android.util.Log import android.util.SparseIntArray import androidx.lifecycle.lifecycleScope 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 import com.shuwei.intelligent.shelves.model.ShelfModel import com.shuwei.intelligent.shelves.serial.SerialPortManager import com.shuwei.intelligent.shelves.task.TaskManager import com.shuwei.intelligent.shelves.utils.UIUtils import com.shuwei.intelligent.shelves.utils.hexToDec import kotlinx.coroutines.launch import java.text.SimpleDateFormat import java.util.Date import java.util.Locale class HomeActivity : BaseActivity() { companion object { private const val TAG = "HomeActivity" //协议头 const val HEADER = "D6DADEDB" //协议尾 const val FOOTER = "FFFF" const val ACTIVE_CMD = "${HEADER}000281C5D70A7D428A4FA67B50F7DACA241938938B4B9CBD73673E9C8E7F2E15062D${FOOTER}" const val LEFT_SHELF_OPEN_CMD = "${HEADER}020101000000000000000000000000000000000000${FOOTER}" const val RIGHT_SHELF_OPEN_CMD = "${HEADER}020100010000000000000000000000000000000000${FOOTER}" //const val TEMPERATURE_CMD = "${HEADER}1001${FOOTER}" const val DEVICE_INFO_CMD = "${HEADER}0301000000000000000000000000${FOOTER}" val list: MutableList = mutableListOf() } private lateinit var binding: ActivityHomeBinding @SuppressLint("NotifyDataSetChanged") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityHomeBinding.inflate(layoutInflater) setContentView(binding.root) updateLeftStatus("1-1冷藏柜 -2°C / 87%") initList() initRecyclerView() lifecycleScope.launch { val openState = SerialPortManager.open() Log.d(TAG, "onCreate: openState=$openState") if (openState) { SerialPortManager.startReceive { data -> runOnUiThread { // 更新UI显示接收数据 runCatching { receiveSerialPortData(data) }.onFailure { it.printStackTrace() } } } SerialPortManager.send(ACTIVE_CMD) //SerialPortManager.send(DEVICE_INFO_CMD) } } TaskManager.startTask() } private fun receiveSerialPortData(data: String) { Log.d(TAG, "receiveSerialPortData: $data") if (data.startsWith(HEADER).not()) { return } val cmd = data.substring(HEADER.length, HEADER.length + 2) when (cmd) { "01" -> { //心跳-01 Log.d(TAG, "receiveSerialPortData:心跳01: $data") } "81" -> { //心跳-81 Log.d(TAG, "receiveSerialPortData:心跳08: $data") heartBeat(data) } "03" -> { //获取设备状态 getDeviceInfo(data) } else -> {} } } private fun heartBeat(data: String) { val weightStartIndex = 2 val weightEndIndex = weightStartIndex + 10 * 8 getWeightInfo( start = weightStartIndex, end = weightEndIndex, data = data ) val temperatureStartIndex = (1 + 10 * 4 + 20 + 1 + 1 + 1 + 1) * 2 val temperatureEndIndex = temperatureStartIndex + 2 val temperatureHex = data.substring(temperatureStartIndex, temperatureEndIndex) val temperature = hexToDec(temperatureHex) updateLeftStatus("1-1冷藏柜 $temperature°C / 87%") } private fun getWeightInfo(start: Int, end: Int, data: String) { var index = 1 var count = start while (count < end) { val weightInfo = data.substring(count, count + 8) var weightHex = "" weightInfo.run { weightHex = substring(6, 8) + substring(4, 6) + substring(2, 4) + substring(0, 2) } var realWeight = 0 if (weightHex.first() in '8'..'F') { //负数 val weightHex2 = "0${weightHex.substring(1)}" realWeight = hexToDec(weightHex2) } else { //整数 realWeight = hexToDec(weightHex) } weightArray.put(index, realWeight) count += 8 index++ } } private fun getDeviceInfo(data: String) { val weightStartIndex = HEADER.length + 4 + 10 val temperatureStartIndex = weightStartIndex + 10 * 8 val temperatureEndIndex = temperatureStartIndex + 2 val temperatureHex = data.substring(temperatureStartIndex, temperatureEndIndex) val temperature = hexToDec(temperatureHex) updateLeftStatus("1-1冷藏柜 $temperature°C / 87%") getWeightInfo( start = weightStartIndex, end = temperatureStartIndex, data = data ) val intent = Intent(ShelfActivity.RECEIVER_DEVICE_INFO) intent.putExtra(ShelfActivity.SHELF_WEIGHT, weightArray[clickIndex]) intent.putExtra(ShelfActivity.RECEIVER_DEVICE_INFO, data) sendBroadcast(intent) } private val weightArray by lazy { SparseIntArray() } private var clickIndex = 0 override fun onDestroy() { lifecycleScope.launch { SerialPortManager.close() } TaskManager.cancelTask() super.onDestroy() } @Suppress("DEPRECATION") private val shelfAdapter by lazy { // val list = viewModel.getCurrentItems() ShelfAdapter(list).apply { setOnDebouncedItemClick { adapter, view, position -> this@HomeActivity.clickIndex = position lifecycleScope.launch { val openCmd = if (list[position].shelfNo in 1..5) LEFT_SHELF_OPEN_CMD else RIGHT_SHELF_OPEN_CMD val openState = SerialPortManager.send(openCmd) if (openState.not()) { UIUtils.toast("${list[position].foodName}柜门开启失败") return@launch } launch(Intent(this@HomeActivity, ShelfActivity::class.java).also { it.putExtra(ShelfActivity.SHELF_MODEL, list[position]) }) { it?.run { val model = getSerializableExtra(ShelfActivity.SHELF_MODEL) as ShelfModel list[position].apply { foodName = model.foodName foodWeight = model.foodWeight storeDate = model.storeDate } notifyItemChanged(position) } } } } } } private fun initRecyclerView() { binding.rvShelf.run { layoutManager = GridLayoutManager(this@HomeActivity, 2, GridLayoutManager.VERTICAL, false) adapter = shelfAdapter } } private fun initList() { // val list: MutableList = mutableListOf() list.add(ShelfModel(shelfNo = 1)) list.add(ShelfModel(shelfNo = 6)) list.add(ShelfModel(shelfNo = 2)) list.add(ShelfModel(shelfNo = 7)) list.add(ShelfModel(shelfNo = 3)) list.add(ShelfModel(shelfNo = 8)) list.add(ShelfModel(shelfNo = 4)) list.add(ShelfModel(shelfNo = 9)) list.add(ShelfModel(shelfNo = 5)) list.add(ShelfModel(shelfNo = 10)) // viewModel.updateItems(list) } private val MM_DD_EEEE__HH_MM_SS = "MM月dd日 EEEE HH:mm:ss" private fun updateDateTime() { val sdf = SimpleDateFormat(MM_DD_EEEE__HH_MM_SS, Locale.CHINA) val dateTime = sdf.format(Date()) updateRightStatus(dateTime) } private val handler = Handler(Looper.getMainLooper()) private val updateTask = object : Runnable { override fun run() { updateDateTime() handler.postDelayed(this, 1000) } } override fun onResume() { super.onResume() hideStatusBar() handler.post(updateTask) } override fun onPause() { super.onPause() handler.removeCallbacks(updateTask) } }