Эх сурвалжийг харах

更新内容
1. 支持设备变化监听,设备状态发生变化时回调调用层

GrayCarbon 1 сар өмнө
parent
commit
e600230d07

+ 78 - 15
app/src/main/java/com/iscs/comm/MainActivity.kt

@@ -1,6 +1,7 @@
 package com.iscs.comm
 
 import android.os.Bundle
+import android.util.Log
 import androidx.activity.ComponentActivity
 import androidx.activity.compose.setContent
 import androidx.activity.enableEdgeToEdge
@@ -17,7 +18,10 @@ import androidx.compose.ui.Modifier
 import androidx.compose.ui.unit.dp
 import androidx.lifecycle.lifecycleScope
 import com.iscs.comm.entity.device.Device
+import com.iscs.comm.entity.device.DeviceKeySlot
 import com.iscs.comm.entity.device.DeviceLockSlot
+import com.iscs.comm.entity.device.status.DeviceStatusKeySlot
+import com.iscs.comm.entity.device.status.DeviceStatusLockSlot
 import com.iscs.comm.intf.IDeviceListener
 import com.iscs.comm.ui.theme.CommunicationDemoTheme
 import kotlinx.coroutines.Dispatchers
@@ -33,40 +37,99 @@ class MainActivity : ComponentActivity() {
         setContent {
             CommunicationDemoTheme {
                 Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
-                    Column {
-                        Text("测试", modifier = Modifier.padding(innerPadding))
+                    Column(modifier = Modifier.padding(10.dp)) {
+                        Text("测试锁底座", modifier = Modifier.padding(innerPadding))
                         Row {
-                            Button({ ctrlLockSlotLock(0, false) }) { Text("开锁0") }
+                            Button({ ctrlLockSlotLock(0, false) }) { Text("0-开") }
                             Spacer(modifier = Modifier.width(10.dp))
-                            Button({ ctrlLockSlotLock(0, true) }) { Text("关锁0") }
+                            Button({ ctrlLockSlotLock(0, true) }) { Text("0-关") }
                             Spacer(modifier = Modifier.width(10.dp))
-                            Button({ ctrlLockSlotLock(1, false) }) { Text("开锁1") }
+                            Button({ ctrlLockSlotLock(1, false) }) { Text("1-开") }
                             Spacer(modifier = Modifier.width(10.dp))
-                            Button({ ctrlLockSlotLock(1, true) }) { Text("关锁1") }
+                            Button({ ctrlLockSlotLock(1, true) }) { Text("1-关") }
+                            Spacer(modifier = Modifier.width(10.dp))
+                            Button({ ctrlLockSlotLock(2, false) }) { Text("2-开") }
+                            Spacer(modifier = Modifier.width(10.dp))
+                            Button({ ctrlLockSlotLock(2, true) }) { Text("2-关") }
+                            Spacer(modifier = Modifier.width(10.dp))
+                            Button({ ctrlLockSlotLock(3, false) }) { Text("3-开") }
+                            Spacer(modifier = Modifier.width(10.dp))
+                            Button({ ctrlLockSlotLock(3, true) }) { Text("3-关") }
+                            Spacer(modifier = Modifier.width(10.dp))
+                            Button({ ctrlLockSlotLock(4, false) }) { Text("4-开") }
+                            Spacer(modifier = Modifier.width(10.dp))
+                            Button({ ctrlLockSlotLock(4, true) }) { Text("4-关") }
+                        }
+                        Text("测试钥匙底座", modifier = Modifier.padding(innerPadding))
+                        Row {
+                            Button({ ctrlKeySlotLock(0, false) }) { Text("0-开锁") }
+                            Spacer(modifier = Modifier.width(10.dp))
+                            Button({ ctrlKeySlotLock(0, true) }) { Text("0-关锁") }
+                            Spacer(modifier = Modifier.width(10.dp))
+                            Button({ ctrlKeySlotCharge(0, true) }) { Text("0-开充电") }
+                            Spacer(modifier = Modifier.width(10.dp))
+                            Button({ ctrlKeySlotCharge(0, false) }) { Text("0-关充电") }
+                            Spacer(modifier = Modifier.width(10.dp))
+                            Button({ ctrlKeySlotLock(1, false) }) { Text("1-开锁") }
+                            Spacer(modifier = Modifier.width(10.dp))
+                            Button({ ctrlKeySlotLock(1, true) }) { Text("1-关锁") }
+                            Spacer(modifier = Modifier.width(10.dp))
+                            Button({ ctrlKeySlotCharge(1, true) }) { Text("1-开充电") }
+                            Spacer(modifier = Modifier.width(10.dp))
+                            Button({ ctrlKeySlotCharge(1, false) }) { Text("1-关充电") }
                         }
                     }
                 }
             }
         }
+
+        // 做SDK初始化操作处理
+        initISCSSDK()
+    }
+
+    fun ctrlLockSlotLock(ch: Int, isLock: Boolean) {
+        val device = list.find { it.frame.cmd == 0x0602 }
+        if (device is DeviceLockSlot) {
+            CommManager.write(device.ctrlSlotLock(ch, isLock))
+        }
+    }
+
+    fun ctrlKeySlotLock(ch: Int, isLock: Boolean) {
+        val device = list.find { it.frame.cmd == 0x0601 }
+        if (device is DeviceKeySlot) {
+            CommManager.write(device.ctrlSlotLock(ch, isLock))
+        }
+    }
+
+    fun ctrlKeySlotCharge(ch: Int, isCharge: Boolean) {
+        val device = list.find { it.frame.cmd == 0x0601 }
+        if (device is DeviceKeySlot) {
+            CommManager.write(device.ctrlSlotCharge(ch, isCharge))
+        }
+    }
+
+    /**
+     * 初始化ISCS SDK 操作
+     */
+    fun initISCSSDK() {
         lifecycleScope.launch(Dispatchers.IO) {
             CommManager.init()
             CommManager.setOnDeviceListener(object : IDeviceListener {
+
                 override fun onDeviceList(devices: List<Device>) {
                     list.addAll(devices)
                 }
 
                 override fun onDeviceChanged(device: Device) {
-
+                    val msg = when (device.deviceStatus) {
+                        is DeviceStatusKeySlot -> (device.deviceStatus as DeviceStatusKeySlot).slotList.toString()
+                        is DeviceStatusLockSlot -> (device.deviceStatus as DeviceStatusLockSlot).slotList.toString()
+                        else -> "未知状态变化"
+                    }
+                    Log.d("xiaoming", "设备状态发生变化了 $msg")
                 }
-            })
-        }
-
-    }
 
-    fun ctrlLockSlotLock(ch: Int, isLock: Boolean) {
-        val device = list.find { it.frame.cmd == 0x0602 }
-        if (device is DeviceLockSlot) {
-            CommManager.write(device.ctrlSlotLock(ch, isLock))
+            })
         }
     }
 }

+ 18 - 4
transport/src/main/java/com/iscs/comm/CommManager.kt

@@ -31,13 +31,25 @@ object CommManager {
     private var deviceListener: IDeviceListener? = null
 
     fun init() {
+        // 初始化前释放资源
+        release()
         // 连接之前先对已连接进行断开连接处理
-        manager?.close()
         manager = CanManager("can0")
         manager?.open()
         initDeviceList()
     }
 
+    /**
+     * 释放资源
+     */
+    fun release() {
+        // 释放管理器
+        manager?.close()
+        manager = null
+        // 释放本地维护的设备列表
+        deviceList.clear()
+    }
+
     /**
      * 设置设备变化监听
      */
@@ -77,7 +89,7 @@ object CommManager {
             delay(20)
         }
         // 遍历一遍设备状态
-        checkDeviceStatus()?.join()
+        checkDeviceStatus(true)?.join()
         // 将设备列表回调给外部
         deviceListener?.onDeviceList(ArrayList(deviceList))
         delay(20)
@@ -91,14 +103,14 @@ object CommManager {
     private fun startDeviceStatusLoop() = manager?.scope?.launch(Dispatchers.IO) {
         // 开启轮询检查
         while (isActive) {
-            checkDeviceStatus()?.join()
+            checkDeviceStatus(false)?.join()
         }
     }
 
     /**
      * 检查设备状态任务
      */
-    private fun checkDeviceStatus() = manager?.scope?.launch(Dispatchers.IO) {
+    private fun checkDeviceStatus(isInit: Boolean) = manager?.scope?.launch(Dispatchers.IO) {
         deviceList.forEach {
             // 根据已有的设备,遍历设备状态
             // 读取设备信息
@@ -108,6 +120,8 @@ object CommManager {
             // 读取设备属性状态
             val sFrame = writeWithResponse(it.ctrlCheckDeviceStatus())
             it.updateDeviceStatus(sFrame)
+            // 设备状态发生变化通知外部
+            if (it.isDeviceStatusChanged() && !isInit) deviceListener?.onDeviceChanged(it)
             // 限制轮询的速度
             delay(50)
         }

+ 10 - 0
transport/src/main/java/com/iscs/comm/entity/device/Device.kt

@@ -27,6 +27,11 @@ abstract class Device(val frame: Frame) {
      */
     protected var id: Int = -1
 
+    /**
+     * 上一次设备状态
+     */
+    protected var lastDeviceStatus = ""
+
     // 数据初始化操作
     init {
         id = frame.cmd
@@ -60,4 +65,9 @@ abstract class Device(val frame: Frame) {
      */
     abstract fun updateDeviceStatus(frame: Frame)
 
+    /**
+     * 设备状态是否发生变化
+     */
+    abstract fun isDeviceStatusChanged(): Boolean
+
 }

+ 18 - 3
transport/src/main/java/com/iscs/comm/entity/device/DeviceKeySlot.kt

@@ -45,6 +45,18 @@ class DeviceKeySlot(frame: Frame) : Device(frame) {
         deviceStatus.updateStatus(frame)
     }
 
+    /**
+     * 校验设备状态是否发生变化
+     */
+    override fun isDeviceStatusChanged(): Boolean {
+        val currentDeviceStatus = (deviceStatus as DeviceStatusKeySlot).slotList.toString()
+        if (lastDeviceStatus != currentDeviceStatus) {
+            lastDeviceStatus = currentDeviceStatus
+            return true
+        }
+        return false
+    }
+
     /**
      * 控制锁仓是否锁定
      *
@@ -53,7 +65,9 @@ class DeviceKeySlot(frame: Frame) : Device(frame) {
      */
     fun ctrlSlotLock(ch: Int, isLock: Boolean): Frame {
         if (ch !in 0..1) return Frame(-1, byteArrayOf())
-        return frame.newFrame().apply { cmd = frame.cmd }.buildCtrlKeySlotLockAndCharge(ch, isLock, false)
+        // 不控制的一项从本地缓存状态中获取写入
+        val status = (deviceStatus as DeviceStatusKeySlot).slotList.find { it.ch == ch }
+        return frame.newFrame().apply { cmd = frame.cmd }.buildCtrlKeySlotLockAndCharge(ch, isLock, status?.isCharging ?: false)
     }
 
     /**
@@ -64,8 +78,9 @@ class DeviceKeySlot(frame: Frame) : Device(frame) {
      */
     fun ctrlSlotCharge(ch: Int, isCharge: Boolean): Frame {
         if (ch !in 0..1) return Frame(-1, byteArrayOf())
-        // 不控制的一项从本地缓存状态中获取
-        return frame.newFrame().apply { cmd = frame.cmd }.buildCtrlKeySlotLockAndCharge(ch, false, isCharge)
+        // 不控制的一项从本地缓存状态中获取写入
+        val status = (deviceStatus as DeviceStatusKeySlot).slotList.find { it.ch == ch }
+        return frame.newFrame().apply { cmd = frame.cmd }.buildCtrlKeySlotLockAndCharge(ch, status?.isSlotLock ?: false, isCharge)
     }
 
     /**

+ 13 - 0
transport/src/main/java/com/iscs/comm/entity/device/DeviceLockSlot.kt

@@ -2,6 +2,7 @@ package com.iscs.comm.entity.device
 
 import com.iscs.comm.entity.Frame
 import com.iscs.comm.entity.device.status.DeviceStatus
+import com.iscs.comm.entity.device.status.DeviceStatusKeySlot
 import com.iscs.comm.entity.device.status.DeviceStatusLockSlot
 import com.iscs.comm.enums.DeviceType
 import com.iscs.comm.extension.buildCheckDeviceStatus
@@ -38,6 +39,18 @@ class DeviceLockSlot(frame: Frame) : Device(frame) {
         deviceStatus.updateStatus(frame)
     }
 
+    /**
+     * 校验设备状态是否发生变化
+     */
+    override fun isDeviceStatusChanged(): Boolean {
+        val currentDeviceStatus = (deviceStatus as DeviceStatusLockSlot).slotList.toString()
+        if (lastDeviceStatus != currentDeviceStatus) {
+            lastDeviceStatus = currentDeviceStatus
+            return true
+        }
+        return false
+    }
+
     /**
      * 控制锁仓是否锁定
      *

+ 4 - 0
transport/src/main/java/com/iscs/comm/entity/device/DeviceNone.kt

@@ -16,6 +16,10 @@ class DeviceNone(frame: Frame) : Device(frame) {
 
     }
 
+    override fun isDeviceStatusChanged(): Boolean {
+        return false
+    }
+
     override fun ctrlCheckDeviceStatus(): Frame {
         return frame.newFrame().apply { cmd = frame.cmd }.buildCheckDeviceStatus()
     }

+ 2 - 0
transport/src/main/java/com/iscs/comm/extension/CommFrameExt.kt

@@ -6,6 +6,7 @@ import com.iscs.comm.protocol.CanProtocol.CAN_KEY_RW
 import com.iscs.comm.protocol.CanProtocol.CAN_KEY_STATUS
 import com.iscs.comm.protocol.CanProtocol.CAN_READ_CMD
 import com.iscs.comm.protocol.CanProtocol.CAN_WRITE_CMD_2BYTE
+import com.iscs.comm.utils.ISCSLog
 
 
 /**
@@ -58,6 +59,7 @@ fun Frame.buildCtrlKeySlotLockAndCharge(ch: Int, isLock: Boolean, isCharge: Bool
     val value = ((if (isCharge) 1 else 0) shl 1) + (if (isLock) 1 else 0)
     val ctrl = if (ch == 0) value else if (ch == 1) value shl 4 else ((value shl 4) or value)
     val work = if (ch == 0) 0B00000011 else if (ch == 1) 0B00110000 else 0B00110011
+    ISCSLog.i("CommFrameExt", "ctrl = ${ctrl.toByte().toBinaryString()} work = ${work.toByte().toBinaryString()}")
     data = byteArrayOf(
         CAN_WRITE_CMD_2BYTE.toByte(), (CAN_KEY_RW and 0xFF).toByte(), ((CAN_KEY_RW shr 8) and 0xFF).toByte(), 0x00,
         ctrl.toByte(), work.toByte(), 0x00, 0x00