ソースを参照

refactor(更新)
- 硬件监听设置

周文健 5 ヶ月 前
コミット
1e01f9f424

+ 2 - 0
app/src/main/java/com/grkj/iscs/ISCSApplication.kt

@@ -4,6 +4,7 @@ import android.R
 import android.app.Application
 import android.content.Context
 import com.grkj.data.di.RepositoryManager
+import com.grkj.ui_base.business.ModbusBusinessManager
 import com.grkj.ui_base.utils.modbus.ModBusController
 import com.kongzue.dialogx.DialogX
 import com.scwang.smart.refresh.footer.ClassicsFooter
@@ -37,6 +38,7 @@ class ISCSApplication : Application() {
         ThreadUtils.runOnIO {
             ModBusController.initDevicesStatus()
             RepositoryManager.init(this@ISCSApplication)
+            ModbusBusinessManager.registerMainListener()
         }
     }
 

+ 6 - 0
data/src/main/java/com/grkj/data/dao/JobTicketDao.kt

@@ -337,4 +337,10 @@ interface JobTicketDao {
      */
     @Update
     fun updateIsJobTicketKey(keys: List<IsJobTicketKey>)
+
+    /**
+     * 更新锁信息
+     */
+    @Query("update is_lock set update_time = :updateTime")
+    fun updateLockReturn(rfid: String, updateTime: String = TimeUtils.nowString(TimeUtils.DEFAULT_DATE_HOUR_MIN_SEC_FORMAT))
 }

+ 5 - 0
data/src/main/java/com/grkj/data/repository/IJobTicketRepository.kt

@@ -183,4 +183,9 @@ interface IJobTicketRepository {
     )
 
     fun updateKeyTake(ticketId: Long, keyNfc: String, serialNo: String, callback: (Boolean) -> Unit)
+
+    /**
+     * 上报锁具归还
+     */
+    fun updateLockReturn(rfid: String, serialNo: String, callback: () -> Unit)
 }

+ 9 - 0
data/src/main/java/com/grkj/data/repository/impl/JobTicketRepository.kt

@@ -415,6 +415,15 @@ class JobTicketRepository @Inject constructor(
         jobTicketDao.saveIsJobTicketKey(listOf(isJobTicketKey))
     }
 
+    override fun updateLockReturn(
+        rfid: String,
+        serialNo: String,
+        callback: () -> Unit
+    ) {
+        jobTicketDao.updateLockReturn(rfid)
+        callback()
+    }
+
     override fun updateKeyReturn(
         ticketId: Long,
         keyNfc: String,

+ 338 - 0
ui-base/src/main/java/com/grkj/ui_base/business/ModbusBusinessManager.kt

@@ -6,6 +6,8 @@ import com.grkj.data.model.local.DeviceTakeUpdate
 import com.grkj.data.model.req.LockTakeUpdateReq
 import com.grkj.ui_base.R
 import com.grkj.data.data.DictConstants
+import com.grkj.data.data.MainDomainData
+import com.grkj.ui_base.listeners.DeviceListener
 import com.grkj.ui_base.utils.CommonUtils
 import com.grkj.ui_base.utils.Executor
 import com.grkj.ui_base.utils.SPUtils
@@ -14,7 +16,9 @@ import com.grkj.ui_base.utils.ble.BleConst
 import com.grkj.ui_base.utils.event.DeviceTakeUpdateEvent
 import com.grkj.ui_base.utils.event.LoadingEvent
 import com.grkj.ui_base.utils.event.UpdateTicketProgressEvent
+import com.grkj.ui_base.utils.extension.removeLeadingZeros
 import com.grkj.ui_base.utils.extension.serialNo
+import com.grkj.ui_base.utils.extension.toHexStrings
 import com.grkj.ui_base.utils.modbus.DeviceConst
 import com.grkj.ui_base.utils.modbus.DockBean
 import com.grkj.ui_base.utils.modbus.ModBusController
@@ -25,6 +29,7 @@ import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.async
 import kotlinx.coroutines.withContext
 import org.slf4j.LoggerFactory
+import kotlin.plus
 
 /**
  * 硬件业务管理
@@ -35,6 +40,27 @@ object ModbusBusinessManager {
     // 设备待取列表(需要报给后台的列表,等实际取完再上报)
     val mDeviceTakeList = mutableListOf<DeviceTakeUpdate>()
 
+    private val listeners = ArrayList<DeviceListener>()
+
+    /**
+     * 注册状态监听
+     */
+    fun registerStatusListener(key: Any, listener: (DockBean) -> Unit) {
+        listeners.add(DeviceListener(key, listener))
+    }
+
+    /**
+     * 取消注册状态监听
+     */
+    fun unregisterListener(key: Any) {
+        val it = listeners.iterator()
+        while (it.hasNext()) {
+            if (it.next().key == key) {
+                it.remove()
+            }
+        }
+    }
+
     /**
      * 添加待更新取出状态的设备
      */
@@ -228,4 +254,316 @@ object ModbusBusinessManager {
             }
         }
     }
+
+    /**
+     * 硬件状态
+     * 1、检测到有钥匙
+     * 2、上锁
+     * 3、开启充电
+     * 4、蓝牙连接
+     * 5、蓝牙数据通讯
+     */
+    private fun deviceStatusHandle(res: Any) {
+        logger.info("硬件状态:${(res as List<ByteArray>).map { it.toHexStrings() }}")
+        if (res.isEmpty() || res.any { it.isEmpty() }) {
+            var tipStr = CommonUtils.getStr(R.string.no_response_board_exists) + " : "
+            val addressList = mutableListOf<String>()
+
+            ModBusController.modBusManager?.mSlaveAddressList?.forEach { itDock ->
+                if (res.none { it.isNotEmpty() && it[0] == itDock }) {
+                    addressList.add("0x${String.format("%02X", itDock)}")
+                }
+            }
+            tipStr += addressList
+            PopTip.tip(tipStr)
+        }
+        res.forEachIndexed { index, bytes ->
+            val dockBean = ModBusController.updateStatus(bytes) ?: return@forEachIndexed
+            ModBusController.isInitReady = true
+            if (MainDomainData.userInfo == null) {
+                return@forEachIndexed
+            }
+            when (dockBean.type) {
+                DeviceConst.DOCK_TYPE_KEY -> {
+                    dockBean.getKeyList().forEach { keyBean ->
+                        if (keyBean.isExist) {
+                            // 放回钥匙,读取rfid
+                            ModBusController.readKeyRfid(
+                                dockBean.addr, keyBean.idx
+                            ) { idx, res ->
+                                ModBusController.controlKeyCharge(
+                                    true, keyBean.idx, dockBean.addr
+                                )
+                                if (res.size < 11) {
+                                    logger.error("Key rfid error")
+                                    return@readKeyRfid
+                                }
+                                val rfid =
+                                    res.copyOfRange(3, 11).toHexStrings(false).removeLeadingZeros()
+                                ThreadUtils.runOnIO {
+                                    val slotStatus =
+                                        async { DataBusiness.fetchDict(DictConstants.KEY_SLOT_STATUS) }
+                                    val slotType =
+                                        async { DataBusiness.fetchDict(DictConstants.KEY_SLOT_TYPE) }
+                                    val slotsPageReq = async { DataBusiness.getSlotsPage() }
+                                    val keyStatusReq =
+                                        async { DataBusiness.fetchDict(DictConstants.KEY_KEY_STATUS) }
+                                    val keyPageReq = async { DataBusiness.getKeyPage() }
+                                    var keyStatus = keyStatusReq.await()
+                                    var keyData = keyPageReq.await()
+                                    val slotsPage = slotsPageReq.await()
+                                    val slotStatusList = slotStatus.await()
+                                    val slotTypeList = slotType.await()
+                                    //锁钥匙未异常正常请求锁数据,关锁
+                                    if (rfid in (keyData?.records?.filter { it.exStatus == keyStatus.find { it.dictLabel == "异常" }?.dictValue }
+                                            ?.map { it.keyNfc }?.toMutableList()
+                                            ?: mutableListOf())
+                                    ) {
+                                        PopTip.tip(
+                                            CommonUtils.getStr(R.string.key_exception_tag)
+                                        )
+                                    } else if (slotsPage?.records?.filter {
+                                            it.slotType == slotTypeList.find { d -> d.dictLabel == "钥匙" }?.dictValue && it.status == slotStatusList.find { d -> d.dictLabel == "异常" }?.dictValue
+                                        }
+                                            ?.find { it.row?.toInt() == dockBean.row && it.col?.toInt() == (dockBean.col + (keyBean.idx) * 2) } != null) {
+                                        PopTip.tip(
+                                            CommonUtils.getStr(R.string.slot_exception_tag)
+                                        )
+                                    } else {
+                                        ModBusController.updateKeyRfid(
+                                            dockBean.addr, keyBean.idx, rfid
+                                        )
+                                        // 放回钥匙,上锁
+                                        ModBusController.controlKeyBuckle(
+                                            false, keyBean.idx, dockBean.addr
+                                        ) {
+                                            RepositoryManager.hardwareRepo.getKeyInfo(rfid) {
+                                                if (it != null && !it.macAddress.isNullOrEmpty()) {
+                                                    ModBusController.updateKeyMac(
+                                                        dockBean.addr,
+                                                        keyBean.idx,
+                                                        it.macAddress ?: ""
+                                                    )
+                                                    ModBusController.updateKeyReadyStatus(
+                                                        it.macAddress ?: "", false, 5
+                                                    )
+                                                } else {
+                                                    logger.error("Get key info fail : $rfid")
+                                                    PopTip.tip(R.string.get_key_info_fail)
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        } else if (!keyBean.isCharging) {//增加充电判断,防止无线充电干扰锁仓状态导致判断为取出
+                            // 移出待连监听集合,防止connectKey循环失败
+                            keyBean.mac?.let {
+                                BleConnectionManager.unregisterConnectListener(it)
+                            }
+                            DeviceTakeUpdateEvent.sendDeviceTakeEvent(
+                                DeviceConst.DEVICE_TYPE_KEY,
+                                keyBean.rfid
+                            )
+                        }
+                    }
+                }
+
+                DeviceConst.DOCK_TYPE_LOCK -> {
+                    dockBean.getLockList().forEach { lockBean ->
+                        if (lockBean.isExist) {
+                            ModBusController.readLockRfid(dockBean.addr, lockBean.idx) { res ->
+                                if (res.size < 11) {
+                                    logger.error("Lock rfid error")
+                                    return@readLockRfid
+                                }
+                                val rfid =
+                                    res.copyOfRange(3, 11).toHexStrings(false).removeLeadingZeros()
+                                ModBusController.updateLockRfid(
+                                    dockBean.addr, lockBean.idx, rfid
+                                )
+                                ThreadUtils.runOnIO {
+                                    val lockStatusReq =
+                                        async { DataBusiness.fetchDict(DictConstants.KEY_PAD_LOCK_STATUS) }
+                                    val slotStatus =
+                                        async { DataBusiness.fetchDict(DictConstants.KEY_SLOT_STATUS) }
+                                    val slotType =
+                                        async { DataBusiness.fetchDict(DictConstants.KEY_SLOT_TYPE) }
+                                    val slotsPageReq = async { DataBusiness.getSlotsPage() }
+                                    var lockStatus = lockStatusReq.await()
+                                    val slotsPage = slotsPageReq.await()
+                                    val slotStatusList = slotStatus.await()
+                                    val slotTypeList = slotType.await()
+                                    RepositoryManager.hardwareRepo.getIsLockPage { lockData ->
+                                        //锁rfid未异常正常请求锁数据,关锁
+                                        if (rfid in (lockData?.records?.filter { it.exStatus == lockStatus.find { it.dictLabel == "异常" }?.dictValue }
+                                                ?.map { it.lockNfc }?.toMutableList()
+                                                ?: mutableListOf())
+                                        ) {
+                                            PopTip.tip(R.string.lock_exception_tag)
+                                        } else if (slotsPage?.records?.filter {
+                                                it.slotType == slotTypeList.find { d -> d.dictLabel == "锁" }?.dictValue && it.status == slotStatusList.find { d -> d.dictLabel == "异常" }?.dictValue
+                                            }
+                                                ?.find { it.row?.toInt() == dockBean.row && (lockBean.idx + 1) == it.col?.toInt() } != null) {
+                                            PopTip.tip(R.string.slot_exception_tag)
+                                        } else {
+                                            RepositoryManager.hardwareRepo.getLockInfo(rfid) {
+                                                if (it != null) {
+                                                    // TODO 考虑快速拿取
+                                                    ModBusController.controlLockBuckle(
+                                                        false, dockBean.addr, lockBean.idx
+                                                    ) { itRst ->
+                                                        if (itRst.isNotEmpty()) {
+                                                            // 上报锁具信息
+                                                            RepositoryManager.jobTicketRepo.updateLockReturn(
+                                                                rfid,
+                                                                SIKCore.getApplication().serialNo()
+                                                            ) {}
+                                                        }
+                                                    }
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        } else {
+                            logger.info("挂锁取出-:${lockBean.rfid}")
+                            DeviceTakeUpdateEvent.sendDeviceTakeEvent(
+                                DeviceConst.DEVICE_TYPE_LOCK,
+                                lockBean.rfid
+                            )
+                        }
+                    }
+                }
+
+                DeviceConst.DOCK_TYPE_ELEC_LOCK_BOARD -> {
+                    // TODO 占位
+                }
+
+                DeviceConst.DOCK_TYPE_PORTABLE -> {
+                    // TODO 便携式待完善
+                    dockBean.deviceList.forEach { deviceBean ->
+                        if (deviceBean.isExist) {
+                            when (deviceBean.type) {
+                                DeviceConst.DEVICE_TYPE_KEY -> {
+                                    ModBusController.readKeyRfid(
+                                        dockBean.addr, deviceBean.idx
+                                    ) { idx, res ->
+                                        if (res.size < 11) {
+                                            logger.error("Key rfid error")
+                                            return@readKeyRfid
+                                        }
+                                        val rfid = res.copyOfRange(3, 11).toHexStrings(false)
+                                            .removeLeadingZeros()
+                                        ModBusController.updateKeyRfid(
+                                            dockBean.addr, deviceBean.idx, rfid
+                                        )
+                                        RepositoryManager.hardwareRepo.getKeyInfo(rfid) {
+                                            ModBusController.updateKeyNewHardware(
+                                                dockBean.addr, deviceBean.idx, it == null
+                                            )
+                                            if (it != null && !it.macAddress.isNullOrEmpty()) {
+                                                ModBusController.updateKeyMac(
+                                                    dockBean.addr,
+                                                    deviceBean.idx,
+                                                    it.macAddress ?: ""
+                                                )
+//                                                    showKeyReturnDialog(it.macAddress, isLeft, dockBean.addr)
+                                            } else {
+                                                PopTip.tip(R.string.get_key_info_fail)
+                                            }
+                                        }
+                                        // TODO 蓝牙通信
+                                    }
+                                }
+
+                                DeviceConst.DEVICE_TYPE_LOCK -> {
+                                    ModBusController.readLockRfid(
+                                        dockBean.addr, deviceBean.idx
+                                    ) { res ->
+                                        if (res.size < 11) {
+                                            logger.error("Lock rfid error")
+                                            return@readLockRfid
+                                        }
+                                        val rfid = res.copyOfRange(3, 11).toHexStrings(false)
+                                            .removeLeadingZeros()
+                                        ModBusController.updateLockRfid(
+                                            dockBean.addr, deviceBean.idx, rfid
+                                        )
+                                        ThreadUtils.runOnIO {
+                                            val lockStatusReq = async {
+                                                DataBusiness.fetchDict(
+                                                    DictConstants.KEY_PAD_LOCK_STATUS
+                                                )
+                                            }
+                                            var lockStatus = lockStatusReq.await()
+                                            RepositoryManager.hardwareRepo.getIsLockPage { lockData ->
+                                                //锁rfid未异常正常请求锁数据,关锁
+                                                if (rfid !in (lockData?.records?.filter { it.exStatus == lockStatus.find { it.dictLabel == "异常" }?.dictValue }
+                                                        ?.map { it.lockNfc }?.toMutableList()
+                                                        ?: mutableListOf())
+                                                ) {
+                                                    RepositoryManager.hardwareRepo.getLockInfo(rfid) {
+                                                        ModBusController.updateLockNewHardware(
+                                                            dockBean.addr,
+                                                            deviceBean.idx,
+                                                            it == null
+                                                        )
+                                                        if (it != null) {
+                                                            // TODO 考虑快速拿取
+                                                            ModBusController.controlLockBuckle(
+                                                                false, dockBean.addr, deviceBean.idx
+                                                            ) { itRst ->
+                                                                if (itRst.isNotEmpty()) {
+                                                                    // 上报锁具信息
+                                                                    RepositoryManager.jobTicketRepo.updateLockReturn(
+                                                                        rfid,
+                                                                        SIKCore.getApplication()
+                                                                            .serialNo()
+                                                                    ) {}
+                                                                }
+                                                            }
+                                                        }
+                                                    }
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+
+                                DeviceConst.DEVICE_TYPE_CARD -> {
+                                    ModBusController.readPortalCaseCardRfid(dockBean.addr) { res ->
+                                        if (res.size < 11) {
+                                            logger.error("Portal Case card rfid error")
+                                            return@readPortalCaseCardRfid
+                                        }
+                                        val rfid = res.copyOfRange(3, 11).toHexStrings(false)
+                                            .removeLeadingZeros()
+                                        logger.info("卡片RFID : $rfid")
+                                    }
+                                }
+
+                                DeviceConst.DEVICE_TYPE_FINGERPRINT -> {
+
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            Executor.delayOnMain(200) {
+                listeners.forEach { it.callBack(dockBean) }
+            }
+        }
+    }
+
+    /**
+     * 总的监听,做预处理,其余的所有监听均使用本监听处理后的数据,只允许调用一次
+     */
+    fun registerMainListener() {
+        ModBusController.registerStatusListener(this) { res ->
+            deviceStatusHandle(res)
+        }
+    }
 }

+ 8 - 0
ui-base/src/main/java/com/grkj/ui_base/listeners/DeviceListener.kt

@@ -0,0 +1,8 @@
+package com.grkj.ui_base.listeners
+
+import com.grkj.ui_base.utils.modbus.DockBean
+
+// Modbus数据页面监听
+class DeviceListener(
+    val key: Any, val callBack: (DockBean) -> Unit
+)

+ 2 - 2
ui-base/src/main/java/com/grkj/ui_base/utils/event/DeviceTakeUpdateEvent.kt

@@ -12,10 +12,10 @@ class DeviceTakeUpdateEvent(
 ) {
     companion object {
         /**
-         * 发送当前模式通知
+         * 发送设备取出通知
          */
         @JvmStatic
-        fun sendCurrentModeEvent(
+        fun sendDeviceTakeEvent(
             deviceType: Int,    // 0:钥匙 1:挂锁
             nfc: String?
         ) {

+ 3 - 3
ui-base/src/main/java/com/grkj/ui_base/utils/modbus/ModBusController.kt

@@ -201,7 +201,7 @@ object ModBusController {
                 dockBean.getKeyList().forEach { key ->
                     if (key.isExist) {
                         logger.info("initKey : ${dockBean.addr} : ${key.idx == 0}")
-                        readKeyRfid(dockBean.addr, key.idx) { isLeft, res ->
+                        readKeyRfid(dockBean.addr, key.idx) { idx, res ->
                             if (res.size < 11) {
                                 logger.error("Key rfid error")
                                 return@readKeyRfid
@@ -563,12 +563,12 @@ object ModBusController {
      * 读取钥匙RFID
      */
     fun readKeyRfid(
-        slaveAddress: Byte?, idx: Int, done: ((isLeft: Boolean, res: ByteArray) -> Unit)? = null
+        slaveAddress: Byte?, idx: Int, done: ((idx: Int, res: ByteArray) -> Unit)? = null
     ) {
         slaveAddress?.let {
             ModBusCMDHelper.generateRfidCmd(idx)?.let { cmd ->
                 modBusManager?.sendTo(it, cmd) {
-                    done?.invoke(idx == 0, it)
+                    done?.invoke(idx, it)
                 }
             }
         }