|
|
@@ -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)
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|