| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138 |
- package com.grkj.iscs_mars
- //todo 所有蓝牙包替换com.clj. -> com.clj.
- import android.content.Context
- import android.content.Intent
- import androidx.appcompat.app.AppCompatActivity
- import androidx.lifecycle.MutableLiveData
- import com.clj.fastble.BleManager
- import com.clj.fastble.data.BleDevice
- import com.clj.fastble.exception.BleException
- import com.google.gson.Gson
- import com.grkj.iscs_mars.ble.BleBean
- import com.grkj.iscs_mars.ble.BleCmdManager
- import com.grkj.iscs_mars.ble.BleConnectionManager
- import com.grkj.iscs_mars.ble.BleConst
- import com.grkj.iscs_mars.ble.BleConst.STATUS_READY
- import com.grkj.iscs_mars.ble.BleConst.STATUS_WORK
- import com.grkj.iscs_mars.ble.BleUtil
- import com.grkj.iscs_mars.ble.CustomBleWriteCallback
- import com.grkj.iscs_mars.extentions.removeLeadingZeros
- import com.grkj.iscs_mars.extentions.serialNo
- import com.grkj.iscs_mars.extentions.startsWith
- import com.grkj.iscs_mars.extentions.toHexStrings
- import com.grkj.iscs_mars.modbus.DockBean
- import com.grkj.iscs_mars.modbus.ModBusController
- import com.grkj.iscs_mars.modbus.ModBusController.dockList
- import com.grkj.iscs_mars.modbus.ModBusController.getOneKey
- import com.grkj.iscs_mars.model.Constants
- import com.grkj.iscs_mars.model.Constants.USER_TYPE_LOCKER
- import com.grkj.iscs_mars.model.DeviceConst.DEVICE_TYPE_CARD
- import com.grkj.iscs_mars.model.DeviceConst.DEVICE_TYPE_FINGERPRINT
- import com.grkj.iscs_mars.model.DeviceConst.DEVICE_TYPE_KEY
- import com.grkj.iscs_mars.model.DeviceConst.DEVICE_TYPE_LOCK
- import com.grkj.iscs_mars.model.DeviceConst.DOCK_TYPE_ELEC_LOCK_BOARD
- import com.grkj.iscs_mars.model.DeviceConst.DOCK_TYPE_KEY
- import com.grkj.iscs_mars.model.DeviceConst.DOCK_TYPE_LOCK
- import com.grkj.iscs_mars.model.DeviceConst.DOCK_TYPE_PORTABLE
- import com.grkj.iscs_mars.model.DictAndSystemConstants
- import com.grkj.iscs_mars.model.ISCSDomainData
- import com.grkj.iscs_mars.model.bo.DeviceTakeUpdateBO
- import com.grkj.iscs_mars.model.bo.UpdateKeyReturnBO
- import com.grkj.iscs_mars.model.bo.WorkTicketGetBO
- import com.grkj.iscs_mars.model.bo.WorkTicketSendBO
- import com.grkj.iscs_mars.model.bo.WorkTicketSendBO.LockListBO
- import com.grkj.iscs_mars.model.eventmsg.CurrentModeMsg
- import com.grkj.iscs_mars.model.eventmsg.DeviceExceptionMsg
- import com.grkj.iscs_mars.model.eventmsg.DeviceTakeUpdateMsg
- import com.grkj.iscs_mars.model.eventmsg.LoadingMsg
- import com.grkj.iscs_mars.model.eventmsg.MsgEvent
- import com.grkj.iscs_mars.model.eventmsg.MsgEventConstants
- import com.grkj.iscs_mars.model.eventmsg.MsgEventConstants.MSG_EVENT_CURRENT_MODE
- import com.grkj.iscs_mars.model.eventmsg.MsgEventConstants.MSG_EVENT_DEVICE_EXCEPTION
- import com.grkj.iscs_mars.model.eventmsg.MsgEventConstants.MSG_EVENT_DEVICE_TAKE_UPDATE
- import com.grkj.iscs_mars.model.eventmsg.MsgEventConstants.MSG_EVENT_LOADING
- import com.grkj.iscs_mars.model.eventmsg.MsgEventConstants.MSG_EVENT_SWITCH_COLLECTION_UPDATE
- import com.grkj.iscs_mars.model.eventmsg.MsgEventConstants.MSG_EVENT_SWITCH_MODE
- import com.grkj.iscs_mars.model.eventmsg.MsgEventConstants.MSG_EVENT_UPDATE_TICKET_PROGRESS
- import com.grkj.iscs_mars.model.eventmsg.SwitchModeMsg
- import com.grkj.iscs_mars.model.eventmsg.UpdateTicketProgressMsg
- import com.grkj.iscs_mars.model.vo.dict.CommonDictRespVO
- import com.grkj.iscs_mars.model.vo.hardware.CabinetSlotsRespVo
- import com.grkj.iscs_mars.model.vo.hardware.SwitchListReqVO
- import com.grkj.iscs_mars.model.vo.key.KeyPageRespVO
- import com.grkj.iscs_mars.model.vo.lock.LockPageRespVO
- import com.grkj.iscs_mars.model.vo.lock.LockTakeUpdateReqVO
- import com.grkj.iscs_mars.model.vo.ticket.LockPointUpdateReqVO
- import com.grkj.iscs_mars.model.vo.ticket.TicketDetailRespVO
- import com.grkj.iscs_mars.service.CheckKeyInfoTask
- import com.grkj.iscs_mars.util.ActivityUtils
- import com.grkj.iscs_mars.util.CommonUtils
- import com.grkj.iscs_mars.util.Executor
- import com.grkj.iscs_mars.util.NetApi
- import com.grkj.iscs_mars.util.SPUtils
- import com.grkj.iscs_mars.util.ToastUtils
- import com.grkj.iscs_mars.util.log.LogUtil
- import com.grkj.iscs_mars.view.activity.LoginActivity
- import com.grkj.iscs_mars.view.base.BaseActivity
- import com.grkj.iscs_mars.view.dialog.TipDialog
- import com.sik.cronjob.managers.CronJobScanner
- import com.sik.sikcore.SIKCore
- import com.sik.sikcore.date.TimeUtils
- import com.sik.sikcore.thread.ThreadUtils
- import kotlinx.coroutines.Dispatchers
- import kotlinx.coroutines.async
- import kotlinx.coroutines.suspendCancellableCoroutine
- import kotlinx.coroutines.withContext
- import kotlin.coroutines.resume
- /**
- * 业务层管理
- */
- object BusinessManager {
- // 消息总线
- val mEventBus = MutableLiveData<MsgEvent>()
- @JvmStatic
- @Volatile
- // 已连接的蓝牙钥匙集合
- var deviceList: MutableList<BleBean> = mutableListOf()
- // Modbus数据页面监听
- class DeviceListener(
- val key: Any, val callBack: (DockBean) -> Unit
- )
- private val listeners = ArrayList<DeviceListener>()
- private var initListener: (() -> Unit)? = null
- /**
- * 断开连接任务
- */
- private val disconnectJob: HashMap<String, String> = hashMapOf()
- // 归还设备是否需要登录
- var NEED_AUTH = true
- // 归还设备是否需要登录及角色验证
- var CAN_RETURN = true
- get() {
- val loginUser = SPUtils.getLoginUser(MyApplication.instance!!.applicationContext!!)
- return (NEED_AUTH && loginUser != null) || !NEED_AUTH
- }
- // 设备待取列表(需要报给后台的列表,等实际取完再上报)
- @JvmStatic
- val mDeviceTakeList = mutableListOf<DeviceTakeUpdateBO>()
- // 是否是测试人员登录的
- var isTestMode = false
- // 有问题的钥匙的列表 - rfid
- var mExceptionKeyList = mutableListOf<String>()
- /**
- * 初始化消息总线
- */
- fun initMsgEventBus() {
- mEventBus.observeForever {
- LogUtil.i("msgEvent : $it")
- when (it.code) {
- // loading消息
- MSG_EVENT_LOADING -> {
- Executor.runOnMain {
- val loadingMsg = it.data as LoadingMsg
- (ActivityUtils.currentActivity() as BaseActivity<*>).handleLoading(
- loadingMsg.isShow, loadingMsg.loadingText
- )
- }
- }
- // 设备取出
- MSG_EVENT_DEVICE_TAKE_UPDATE -> {
- handleDeviceTake(it.data as DeviceTakeUpdateMsg)
- }
- MsgEventConstants.MSG_EVENT_INIT_KEY_COMPLETE -> {
- val job = CronJobScanner.scanJobs(CheckKeyInfoTask())
- MyApplication.cronJobManager.registerJobs(job)
- }
- // 钥匙当前模式
- MSG_EVENT_CURRENT_MODE -> {
- handleCurrentMode(it.data as CurrentModeMsg)
- }
- // 钥匙切换模式结果
- MSG_EVENT_SWITCH_MODE -> {
- when ((it.data as SwitchModeMsg).job) {
- // 工作模式
- 1 -> {
- if (it.data.res == 1) {
- // 只能在这里断开,不能全部断开
- BleManager.getInstance().disconnect(it.data.bleBean.bleDevice)
- deviceList.removeIf { device -> device.bleDevice.mac == it.data.bleBean.bleDevice.mac }
- // 打开钥匙卡扣
- val keyBean =
- ModBusController.getKeyByMac(it.data.bleBean.bleDevice.mac)
- if (keyBean == null) {
- sendEventMsg(
- MsgEvent(
- MSG_EVENT_LOADING,
- LoadingMsg(false, "未找到钥匙信息", false)
- )
- )
- ToastUtils.tip(R.string.key_not_exists)
- } else {
- sendLoadingEventMsg(CommonUtils.getStr(R.string.take_out_key_tip))
- val dock =
- ModBusController.getDockByKeyMac(it.data.bleBean.bleDevice.mac)
- keyBean.isReady = false
- ModBusController.controlKeyBuckle(
- true, keyBean.isLeft, dock?.addr
- )
- ModBusController.updateKeyReadyStatus(
- it.data.bleBean.bleDevice.mac, false, 1
- )
- ToastUtils.tip(R.string.take_out_key)
- }
- } else {
- LogUtil.e("切换工作模式失败 : ${it.data.bleBean.bleDevice.mac}")
- Executor.delayOnMain(500) {
- switchWorkMode(it.data.bleBean.bleDevice, false)
- }
- }
- }
- // 待机模式
- 2 -> {
- if (it.data.res == 1) {
- ModBusController.updateKeyReadyStatus(
- it.data.bleBean.bleDevice.mac, true, 2
- )
- // 延时再次获取当前状态,触发handleCurrentMode里工作票下发状态检查
- Executor.delayOnMain(500) {
- getCurrentStatus(1, it.data.bleBean.bleDevice)
- }
- } else {
- LogUtil.e("切换待机模式失败 : ${it.data.bleBean.bleDevice.mac}")
- Executor.delayOnMain(500) {
- switchReadyMode(it.data.bleBean.bleDevice)
- }
- }
- }
- }
- }
- MSG_EVENT_SWITCH_COLLECTION_UPDATE -> {
- ThreadUtils.runOnIO {
- val switchStatus =
- NetApi.getDictData(DictAndSystemConstants.KEY_SWITCH_STATUS)
- val switchListReqVOS = ModBusController.getSwitchData().map {
- SwitchListReqVO(
- it.idx.toString(),
- if (it.enabled) switchStatus?.find { it.dictLabel == "打开" }?.dictValue else switchStatus?.find { it.dictLabel == "关闭" }?.dictValue,
- TimeUtils.nowString(TimeUtils.DEFAULT_DATE_HOUR_MIN_SEC_FORMAT)
- )
- }
- NetApi.updateSwitchList(switchListReqVOS) {
- LogUtil.i("开关更新完成")
- }
- }
- }
- }
- }
- }
- /**
- * 连接一把存在的可连接的钥匙
- */
- fun connectExistsKey(exceptKeyMac: List<String> = listOf()) {
- ThreadUtils.runOnIO {
- cancelDisconnectAllJob()
- val connectedDevice = BleManager.getInstance().allConnectedDevice
- if (connectedDevice.isNotEmpty() && connectedDevice.subtract(exceptKeyMac.toSet())
- .isNotEmpty()
- ) {
- LogUtil.i("已有钥匙连接")
- return@runOnIO
- }
- // —— 串行请求1 & 2 ——
- val slotsPage = getSlotsPage()
- // —— 并行加载字典(或按需串行也行) ——
- val slotStatus =
- async { fetchDict<CommonDictRespVO>(DictAndSystemConstants.KEY_SLOT_STATUS) }
- val keyStatus =
- async { fetchDict<CommonDictRespVO>(DictAndSystemConstants.KEY_KEY_STATUS) }
- val slotType =
- async { fetchDict<CommonDictRespVO>(DictAndSystemConstants.KEY_SLOT_TYPE) }
- // 等待字典加载完成
- val slotStatusList = slotStatus.await()
- val keyStatusList = keyStatus.await()
- val slotTypeList = slotType.await()
- withContext(Dispatchers.Default) {
- val keyPage = withContext(Dispatchers.IO) { getKeyPage() }
- getOneKey(
- slotsPage?.records?.filter {
- it.slotType == slotTypeList.find { d -> d.dictLabel == "钥匙" }?.dictValue && it.status == slotStatusList.find { d -> d.dictLabel == "异常" }?.dictValue
- }?.toMutableList() ?: mutableListOf(),
- (keyPage?.records?.filter { it.exStatus == keyStatusList.find { d -> d.dictLabel == "异常" }?.dictValue }
- ?.map { it.keyNfc ?: "" }?.toMutableList() ?: mutableListOf()),
- exceptKeyMac
- )
- }
- }
- }
- /****************************************** ModBus ******************************************/
- /**
- * 链接底座
- */
- fun connectDock(isNeedInit: Boolean = false) {
- ModBusController.interruptReadTrashBinStatus(false)
- ModBusController.start(MyApplication.instance!!.applicationContext)
- ModBusController.unregisterListener(MyApplication.instance!!.applicationContext)
- if (isNeedInit) {
- ModBusController.initDevicesStatus()
- }
- }
- /**
- * 断开底座链接
- */
- fun disconnectDock() {
- ModBusController.stop()
- }
- /**
- * 注册状态监听
- */
- fun registerStatusListener(key: Any, listener: (DockBean) -> Unit) {
- listeners.add(DeviceListener(key, listener))
- }
- /**
- * 注册初始化监听
- */
- fun registerInitListener(listener: () -> Unit) {
- this.initListener = listener
- }
- /**
- * 取消注册初始化监听
- */
- fun unRegisterInitListener() {
- this.initListener = null
- }
- /**
- * 取消注册状态监听
- */
- fun unregisterListener(key: Any) {
- val it = listeners.iterator()
- while (it.hasNext()) {
- if (it.next().key == key) {
- it.remove()
- }
- }
- }
- /**
- * 总的监听,做预处理,其余的所有监听均使用本监听处理后的数据,只允许调用一次
- */
- fun registerMainListener() {
- ModBusController.registerStatusListener(this) { res ->
- deviceStatusHandle(res)
- }
- }
- /**
- * 获取最多电量的钥匙
- */
- fun getMaxPowerKey(): DockBean.KeyBean {
- return ModBusController.getMaxPowerKey()
- }
- /**
- * 硬件状态
- * 1、检测到有钥匙
- * 2、上锁
- * 3、开启充电
- * 4、蓝牙连接
- * 5、蓝牙数据通讯
- */
- private fun deviceStatusHandle(res: Any) {
- LogUtil.i("硬件状态:${(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
- ToastUtils.tip(tipStr)
- }
- res.forEachIndexed { index, bytes ->
- val dockBean = ModBusController.updateStatus(bytes) ?: return@forEachIndexed
- ModBusController.isInitReady = true
- if (!CAN_RETURN) {
- return@forEachIndexed
- }
- when (dockBean.type) {
- DOCK_TYPE_KEY -> {
- dockBean.getKeyList().forEach { keyBean ->
- deviceKeyHandler(dockBean, keyBean)
- }
- }
- DOCK_TYPE_LOCK -> {
- dockBean.getLockList().forEach { lockBean ->
- deviceLockHandler(dockBean, lockBean)
- }
- }
- DOCK_TYPE_ELEC_LOCK_BOARD -> {
- // TODO 占位
- }
- DOCK_TYPE_PORTABLE -> {
- // TODO 便携式待完善
- dockBean.deviceList.forEach { deviceBean ->
- if (deviceBean.isExist) {
- when (deviceBean.type) {
- DEVICE_TYPE_KEY -> {
- deviceKeyHandler(dockBean, deviceBean as DockBean.KeyBean)
- }
- DEVICE_TYPE_LOCK -> {
- deviceLockHandler(dockBean, deviceBean as DockBean.LockBean)
- }
- DEVICE_TYPE_CARD -> {
- ModBusController.readPortalCaseCardRfid(dockBean.addr) { res ->
- if (res.size < 11) {
- LogUtil.e("Portal Case card rfid error")
- return@readPortalCaseCardRfid
- }
- val rfid = res.copyOfRange(3, 11).toHexStrings(false)
- .removeLeadingZeros()
- LogUtil.i("卡片RFID : $rfid")
- }
- }
- DEVICE_TYPE_FINGERPRINT -> {
- }
- }
- }
- }
- }
- }
- Executor.delayOnMain(200) {
- if (!ISCSDomainData.isDeviceRegistration) {
- listeners.forEach { it.callBack(dockBean) }
- }
- }
- }
- Executor.delayOnMain(200) {
- if (ISCSDomainData.isDeviceRegistration) {
- initListener?.invoke()
- }
- }
- }
- /**
- * 挂锁处理
- */
- private fun deviceLockHandler(
- dockBean: DockBean,
- lockBean: DockBean.LockBean
- ) {
- if (lockBean.isExist) {
- ModBusController.readLockRfid(dockBean.addr, lockBean.idx) { res ->
- if (res.size < 11) {
- LogUtil.e("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 { fetchDict<CommonDictRespVO>(DictAndSystemConstants.KEY_PAD_LOCK_STATUS) }
- val slotStatus =
- async { fetchDict<CommonDictRespVO>(DictAndSystemConstants.KEY_SLOT_STATUS) }
- val slotType =
- async { fetchDict<CommonDictRespVO>(DictAndSystemConstants.KEY_SLOT_TYPE) }
- val slotsPageReq = async { getSlotsPage() }
- var lockStatus = lockStatusReq.await()
- val slotsPage = slotsPageReq.await()
- val slotStatusList = slotStatus.await()
- val slotTypeList = slotType.await()
- NetApi.getIsLockPage { lockData ->
- //锁rfid未异常正常请求锁数据,关锁
- if (rfid in (lockData?.records?.filter { it.exStatus == lockStatus.find { it.dictLabel == "异常" }?.dictValue }
- ?.map { it.lockNfc }?.toMutableList()
- ?: mutableListOf())
- ) {
- ToastUtils.tip(
- MyApplication.instance?.applicationContext!!.getString(
- 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) {
- ToastUtils.tip(
- MyApplication.instance?.applicationContext!!.getString(
- R.string.slot_exception_tag
- )
- )
- } else {
- NetApi.getLockInfo(rfid) {
- if (it != null) {
- // TODO 考虑快速拿取
- ModBusController.controlLockBuckle(
- false, dockBean.addr, lockBean.idx
- ) { itRst ->
- if (itRst.isNotEmpty()) {
- // 上报锁具信息
- NetApi.updateLockReturn(
- rfid,
- MyApplication.instance!!.serialNo()
- ) {}
- }
- }
- }
- }
- }
- }
- }
- }
- } else {
- LogUtil.i("挂锁取出-:${lockBean.rfid}")
- sendEventMsg(
- MsgEvent(
- MSG_EVENT_DEVICE_TAKE_UPDATE,
- DeviceTakeUpdateMsg(DEVICE_TYPE_LOCK, lockBean.rfid)
- )
- )
- }
- }
- private fun deviceKeyHandler(dockBean: DockBean, keyBean: DockBean.KeyBean) {
- if (keyBean.isExist) {
- // 放回钥匙,读取rfid
- ModBusController.readKeyRfid(
- dockBean.addr, if (keyBean.isLeft) 0 else 1
- ) { isLeft, res ->
- if (!ISCSDomainData.isDeviceRegistration) {
- ModBusController.controlKeyCharge(
- true, keyBean.isLeft, dockBean.addr
- )
- }
- if (res.size < 11) {
- LogUtil.e("Key rfid error")
- return@readKeyRfid
- }
- val rfid =
- res.copyOfRange(3, 11).toHexStrings(false).removeLeadingZeros()
- ThreadUtils.runOnIO {
- val slotStatus =
- async { fetchDict<CommonDictRespVO>(DictAndSystemConstants.KEY_SLOT_STATUS) }
- val slotType =
- async { fetchDict<CommonDictRespVO>(DictAndSystemConstants.KEY_SLOT_TYPE) }
- val slotsPageReq = async { getSlotsPage() }
- val keyStatusReq =
- async { fetchDict<CommonDictRespVO>(DictAndSystemConstants.KEY_KEY_STATUS) }
- val keyPageReq = async { 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())
- ) {
- ToastUtils.tip(
- MyApplication.instance?.applicationContext!!.getString(
- 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 + (if (keyBean.isLeft) 0 else 1) * 2) } != null) {
- ToastUtils.tip(
- MyApplication.instance?.applicationContext!!.getString(
- R.string.slot_exception_tag
- )
- )
- } else {
- ModBusController.updateKeyRfid(
- dockBean.addr, keyBean.isLeft, rfid
- )
- // 放回钥匙,上锁
- ModBusController.controlKeyBuckle(
- false, keyBean.isLeft, dockBean.addr
- ) {
- NetApi.getKeyInfo(rfid) {
- ModBusController.updateKeyNewHardware(
- dockBean.addr, true, it == null
- )
- if (it != null && !it.macAddress.isNullOrEmpty()) {
- ModBusController.updateKeyMac(
- dockBean.addr, keyBean.isLeft, it.macAddress
- )
- ModBusController.updateKeyReadyStatus(
- it.macAddress, false, 5
- )
- } else {
- LogUtil.e("Get key info fail : $rfid")
- if (!ISCSDomainData.isDeviceRegistration) {
- ToastUtils.tip(R.string.get_key_info_fail)
- }
- ModBusController.controlKeyBuckle(
- true, keyBean.isLeft, dockBean.addr
- )
- }
- }
- }
- }
- }
- }
- } else if (!keyBean.isCharging) {//增加充电判断,防止无线充电干扰锁仓状态导致判断为取出
- // 移出待连监听集合,防止connectKey循环失败
- keyBean.mac?.let {
- unregisterConnectListener(it)
- }
- sendEventMsg(
- MsgEvent(
- MSG_EVENT_DEVICE_TAKE_UPDATE,
- DeviceTakeUpdateMsg(DEVICE_TYPE_KEY, keyBean.rfid)
- )
- )
- }
- }
- /**
- * 更新所有锁仓状态
- */
- fun updateAllBuckleStatus(done: () -> Unit) {
- ModBusController.updateAllBuckleStatus(done)
- }
- /**
- * 更新开关状态
- */
- fun updateSwitchStatus(done: () -> Unit) {
- ModBusController.updateSwitchStatus(done)
- }
- /**
- * 钥匙归还提示确认弹框,当前策略:作业票未完成禁止归还钥匙
- */
- private fun showKeyReturnDialog(onConfirm: () -> Unit) {
- val ctx = ActivityUtils.currentActivity() as BaseActivity<*>
- val dlg = TipDialog(ctx)
- dlg.setTip(ctx.getString(R.string.key_return_tip))
- dlg.setType(TipDialog.TYPE_CONFIRM)
- // 加个选择判断,如果是直接取消弹框而不是点击“确定”,当成确定
- var state = 0
- dlg.setConfirmListener {
- state = 1
- onConfirm.invoke()
- }
- dlg.setOnDismissListener {
- if (state == 0) {
- onConfirm.invoke()
- }
- }
- dlg.show()
- }
- fun readLockBuckleStatus() {
- // TODO slaveIdx暂时写死,调试用
- ModBusController.readBuckleStatus(true, 0) { type, res ->
- LogUtil.i("单slave卡扣状态 : $type - ${res.toHexStrings()}")
- when (type) {
- 0 -> {
- val isLeftLock = (res[4].toInt() shr 0) and 0x1 == 1
- val isRightLock = (res[4].toInt() shr 4) and 0x1 == 1
- LogUtil.i("锁具底座卡扣状态 : $isLeftLock - $isRightLock")
- }
- 1 -> {
- val tempList = mutableListOf<Boolean>()
- for (i in 0..7) {
- tempList.add((res[4].toInt() shr i) and 0x1 == 1)
- }
- LogUtil.i("锁具底座卡扣1-8状态 : $tempList")
- }
- 2 -> {
- val lock9Status = (res[4].toInt() shr 0) and 0x1 == 1
- val lock10Status = (res[4].toInt() shr 1) and 0x1 == 1
- LogUtil.i("锁具底座卡扣9、10状态 : $lock9Status - $lock10Status")
- }
- }
- }
- }
- fun readKeyBuckleStatus() {
- // TODO slaveIdx暂时写死,调试用
- ModBusController.readBuckleStatus(false, 1) { type, res ->
- LogUtil.i("单slave卡扣状态 : $type - ${res.toHexStrings()}")
- // TODO 待验证
- when (type) {
- 0 -> {
- val isLeftLock = (res[4].toInt() shr 0) and 0x1 == 1
- val isRightLock = (res[4].toInt() shr 4) and 0x1 == 1
- LogUtil.i("钥匙底座卡扣状态 : $isLeftLock - $isRightLock")
- }
- 1 -> {
- val tempList = mutableListOf<Boolean>()
- for (i in 0..7) {
- tempList.add((res[4].toInt() shr i) and 0x1 == 1)
- }
- LogUtil.i("锁具底座卡扣1-8状态 : $tempList")
- }
- 2 -> {
- val lock9Status = (res[4].toInt() shr 0) and 0x1 == 1
- val lock10Status = (res[4].toInt() shr 1) and 0x1 == 1
- LogUtil.i("锁具底座卡扣9、10状态 : $lock9Status - $lock10Status")
- }
- }
- }
- }
- // 1. 把 NetApi.get…Page 包成 suspend 函数
- private suspend fun getSlotsPage(): CabinetSlotsRespVo? = suspendCancellableCoroutine { cont ->
- NetApi.getIsLockCabinetSlotsPage { slots ->
- cont.resume(slots)
- }
- }
- private suspend fun getLocksPage(): LockPageRespVO? = suspendCancellableCoroutine { cont ->
- NetApi.getIsLockPage { locks ->
- cont.resume(locks)
- }
- }
- private suspend fun getKeyPage(): KeyPageRespVO? = suspendCancellableCoroutine { cont ->
- NetApi.getIsKeyPage { keys ->
- cont.resume(keys)
- cont.cancel()
- }
- }
- // 2. 把原本同步的字典查询留在 IO 线程
- private suspend fun <T> fetchDict(key: String): List<T> = withContext(Dispatchers.IO) {
- @Suppress("UNCHECKED_CAST") NetApi.getDictData(key) as List<T>
- }
- // 3. 重写 checkEquipCount
- fun checkEquipCount(
- needLockCount: Int,
- isNeedKey: Boolean,
- callBack: (Pair<Byte, DockBean.KeyBean?>?, MutableMap<Byte, MutableList<DockBean.LockBean>>) -> Unit
- ) {
- // 你可以改成接收 CoroutineScope 或者直接在全局 Scope 启动
- ThreadUtils.runOnMain {
- sendLoadingEventMsg(MyApplication.instance?.applicationContext!!.getString(R.string.check_key_and_lock))
- try {
- // —— 串行请求1 & 2 ——
- val slotsPage = getSlotsPage()
- val locksPage = getLocksPage()
- // —— 并行加载字典(或按需串行也行) ——
- val lockStatus =
- async { fetchDict<CommonDictRespVO>(DictAndSystemConstants.KEY_PAD_LOCK_STATUS) }
- val slotStatus =
- async { fetchDict<CommonDictRespVO>(DictAndSystemConstants.KEY_SLOT_STATUS) }
- val slotType =
- async { fetchDict<CommonDictRespVO>(DictAndSystemConstants.KEY_SLOT_TYPE) }
- val keyStatus =
- async { fetchDict<CommonDictRespVO>(DictAndSystemConstants.KEY_KEY_STATUS) }
- // 等待字典加载完成
- val lockStatusList = lockStatus.await()
- val slotStatusList = slotStatus.await()
- val slotTypeList = slotType.await()
- val keyStatusList = keyStatus.await()
- // —— 在 Default 线程做计算密集操作 ——
- val lockMap = withContext(Dispatchers.Default) {
- ModBusController.getLocks(
- needLockCount,
- slotsPage?.records?.filter {
- it.slotType == slotTypeList.find { d -> d.dictLabel == "锁" }?.dictValue && it.status == slotStatusList.find { d -> d.dictLabel == "异常" }?.dictValue
- }?.toMutableList() ?: mutableListOf(),
- locksPage?.records?.filter { it.exStatus == lockStatusList.find { d -> d.dictLabel == "异常" }?.dictValue }
- ?.map { it.lockNfc ?: "" }?.toMutableList() ?: mutableListOf()
- )
- }
- val actualLockCount = lockMap.values.sumBy { it.size }
- // 如果锁不够,提前清空并立刻返回
- if (actualLockCount < needLockCount) {
- ToastUtils.tip(
- MyApplication.instance!!.getString(R.string.lock_is_not_enough)
- )
- callBack(null, mutableMapOf())
- return@runOnMain
- }
- // —— 如果需钥匙,再请求并计算 ——
- var keyPair: Pair<Byte, DockBean.KeyBean?>? = null
- if (isNeedKey) {
- val keyPage = withContext(Dispatchers.IO) { getKeyPage() }
- keyPair = withContext(Dispatchers.Default) {
- getOneKey(
- slotsPage?.records?.filter {
- it.slotType == slotTypeList.find { d -> d.dictLabel == "钥匙" }?.dictValue && it.status == slotStatusList.find { d -> d.dictLabel == "异常" }?.dictValue
- }?.toMutableList() ?: mutableListOf(),
- keyPage?.records?.filter { it.exStatus == keyStatusList.find { d -> d.dictLabel == "异常" }?.dictValue }
- ?.map { it.keyNfc ?: "" }?.toMutableList() ?: mutableListOf()
- )
- }
- if (keyPair == null) {
- ToastUtils.tip(
- MyApplication.instance!!.getString(R.string.no_available_key)
- )
- }
- }
- // —— 全部计算完毕,在主线程一次性回调 ——
- callBack(keyPair, lockMap)
- } catch (e: Exception) {
- // 根据需求处理异常,或把异常信息也通过 callback 返回
- sendLoadingEventMsg(null, false)
- e.printStackTrace()
- ToastUtils.tip("检查设备异常:${e.message}")
- }
- }
- }
- /**
- * 获取开关量数据
- */
- fun getSwitchData(): MutableList<DockBean.SwitchBean> {
- return ModBusController.getSwitchData()
- }
- /****************************************** 蓝牙 ******************************************/
- /******************************************蓝牙通用准备******************************************/
- /**
- * 注册连接监听
- */
- fun registerConnectListener(
- mac: String, connectNow: Boolean = false, callBack: ((
- Boolean, BleBean?
- ) -> Unit)? = null
- ) {
- BleConnectionManager.registerConnectListener(mac, connectNow, callBack)
- }
- /**
- * 连接监听反注册
- */
- fun unregisterConnectListener(mac: String, bleBean: BleBean? = null) {
- BleConnectionManager.unregisterConnectListener(mac, bleBean)
- }
- /******************************************蓝牙通用准备结束******************************************/
- fun getBleDeviceByMac(mac: String?): BleBean? {
- return deviceList.find { it.bleDevice.mac == mac }
- }
- fun getBleBeanByRfid(nfc: String?): BleBean? {
- nfc ?: return null
- ModBusController.getKeyByRfid(nfc)?.mac?.let { itMac ->
- return getBleDeviceByMac(itMac)
- }
- return null
- }
- /**
- * 启动断连任务
- */
- fun launchDisconnectJob(mac: String) {
- val jobId = ThreadUtils.runOnIODelayed(Constants.BLE_DISCONNECT_DELAY_TIME) {
- val bleBean = getBleDeviceByMac(mac)
- bleBean?.bleDevice?.let {
- BleManager.getInstance().disconnect(it)
- }
- }
- disconnectJob[mac] = jobId
- }
- /**
- * 启动断连所有设备任务
- */
- fun launchDisconnectAllJob() {
- deviceList.forEach { bleBean ->
- val jobId = ThreadUtils.runOnIODelayed(Constants.BLE_DISCONNECT_DELAY_TIME) {
- val bleBean = getBleDeviceByMac(bleBean.bleDevice.mac)
- bleBean?.bleDevice?.let {
- BleManager.getInstance().disconnect(it)
- deviceList.removeIf { it == bleBean }
- }
- }
- disconnectJob[bleBean.bleDevice.mac] = jobId
- }
- }
- /**
- * 取消断连所有设备任务
- */
- fun cancelDisconnectAllJob() {
- disconnectJob.forEach {
- ThreadUtils.cancel(it.value)
- }
- }
- /**
- * 取消断连任务
- */
- fun cancelDisconnectJob(mac: String) {
- val jobId = disconnectJob[mac]
- jobId?.let {
- ThreadUtils.cancel(it)
- }
- }
- /**
- * 下发工作票
- */
- private fun sendTicketBusiness(
- isLock: Boolean,
- mac: String,
- ticketDetail: TicketDetailRespVO,
- lockList: MutableList<String?>?,
- activity: AppCompatActivity,
- isNeedLoading: Boolean = false,
- ) {
- registerConnectListener(mac, true) { isDone, bleBean ->
- if (!isDone) {
- sendTicketBusiness(isLock, mac, ticketDetail, lockList, activity, isNeedLoading)
- return@registerConnectListener
- }
- if (bleBean == null) {
- // ToastUtils.tip(R.string.simple_key_is_not_connected)
- LogUtil.e("sendTicketBusiness fail : $mac, bleBean is null")
- return@registerConnectListener
- }
- // 单bleBean json赋值
- bleBean.retryCount = 0
- bleBean.ticketSend = generateTicketSendJson(isLock, ticketDetail, lockList)
- bleBean.ticketSend?.let { itJson ->
- sendTicketWithRetry(itJson, bleBean.bleDevice, isNeedLoading)
- }
- }
- }
- /**
- * 带重试的下发工作票,重试次数3,间隔500ms
- */
- private fun sendTicketWithRetry(
- json: String,
- bleDevice: BleDevice,
- isNeedLoading: Boolean = false,
- maxRetries: Int = 3,
- delayMillis: Long = 500
- ) {
- var retryCount = 0
- fun attemptSend() {
- sendTicket(json, bleDevice, isNeedLoading) { sendRst ->
- if (!sendRst && retryCount < maxRetries) {
- retryCount++
- // 等待一段时间后再次尝试
- Executor.delayOnMain(delayMillis) {
- LogUtil.i("Retry attempt, mac : ${bleDevice.mac}, retryCount : $retryCount")
- attemptSend()
- }
- }
- }
- }
- attemptSend()
- }
- /**
- * 读取工作票完成情况
- */
- private fun getTicketStatusBusiness(
- mac: String, isNeedLoading: Boolean = false
- ) {
- registerConnectListener(mac, true) { isDone, bleBean ->
- if (isDone) {
- Executor.delayOnMain(500) {
- getTicketStatusWithRetry(bleBean!!.bleDevice, isNeedLoading)
- }
- } else {
- if (isNeedLoading) sendEventMsg(
- MsgEvent(
- MSG_EVENT_LOADING, LoadingMsg(false, null, false)
- )
- )
- }
- }
- }
- private fun getTicketStatusWithRetry(
- bleDevice: BleDevice,
- isNeedLoading: Boolean = false,
- maxRetries: Int = 3,
- delayMillis: Long = 500
- ) {
- var retryCount = 0
- fun attemptSend() {
- getTicketStatus(bleDevice, isNeedLoading) { sendRst ->
- if (!sendRst && retryCount < maxRetries) {
- retryCount++
- // 等待一段时间后再次尝试
- Executor.delayOnMain(delayMillis) {
- LogUtil.i("Retry attempt, mac : ${bleDevice.mac}, retryCount : $retryCount")
- attemptSend()
- }
- }
- }
- }
- attemptSend()
- }
- private fun sendTicket(
- jsonStr: String,
- bleDevice: BleDevice,
- isNeedLoading: Boolean = false,
- processCallback: ((Boolean) -> Unit)? = null
- ) {
- if (isNeedLoading) sendEventMsg(
- MsgEvent(
- MSG_EVENT_LOADING,
- LoadingMsg(true, CommonUtils.getStr(R.string.start_to_send_ticket), null)
- )
- )
- BleCmdManager.sendWorkTicket(
- jsonStr, bleDevice = bleDevice, callback = object : CustomBleWriteCallback() {
- override fun onWriteSuccess(current: Int, total: Int, justWrite: ByteArray?) {
- LogUtil.i("sendTicket success")
- if (isNeedLoading) sendEventMsg(
- MsgEvent(
- MSG_EVENT_LOADING,
- LoadingMsg(true, CommonUtils.getStr(R.string.sending_ticket), null)
- )
- )
- }
- override fun onWriteFailure(exception: BleException?) {
- LogUtil.e("sendTicket fail : ${bleDevice.mac}")
- if (isNeedLoading) sendEventMsg(
- MsgEvent(
- MSG_EVENT_LOADING,
- LoadingMsg(false, CommonUtils.getStr(R.string.send_ticket_fail), null)
- )
- )
- processCallback?.invoke(false)
- }
- })
- }
- /**
- * 生成下发工作票Json
- *
- * @param vo 工作票详情
- */
- private fun generateTicketSendJson(
- isLock: Boolean, vo: TicketDetailRespVO, lockList: MutableList<String?>?
- ): String {
- LogUtil.i("generateTicketSendJson : $lockList")
- val bo = WorkTicketSendBO(
- cardNo = SPUtils.getLoginUser(MyApplication.instance!!.applicationContext)?.userCardList?.get(
- 0
- ),
- )
- CommonUtils.getDiffHours(vo.ticketEndTime)?.let {
- bo.effectiveTime = it
- }
- // 有配置则用配置,没用则填充默认密码
- bo.password =
- SPUtils.getLoginUser(MyApplication.instance!!.applicationContext)?.keyCode ?: "123456"
- val dataBO = WorkTicketSendBO.DataBO(
- taskCode = vo.ticketId.toString(), codeId = 1
- )
- val taskList = ArrayList<WorkTicketSendBO.DataBO.DataListBO>()
- vo.ticketPointsVOList?.let { itList ->
- itList.forEach { pointVO ->
- if (vo.noUnlockTicketPointsVOSet?.any { it.pointId == pointVO.pointId } == true && isLock == false) {
- return@forEach
- }
- val task = WorkTicketSendBO.DataBO.DataListBO(
- dataId = pointVO.pointId?.toInt(),
- equipRfidNo = pointVO.pointNfc,
- equipName = pointVO.pointName,
- target = if (isLock) 0 else 1
- )
- if (!isLock) {
- task.infoRfidNo = pointVO.lockNfc
- }
- pointVO.prePointId?.let {
- task.prevId = it.toInt()
- }
- // TODO partCode待补充
- taskList.add(task)
- }
- }
- dataBO.dataList = taskList
- bo.data = mutableListOf(dataBO)
- if (isLock) {
- // TODO 挂锁数组
- if (!lockList.isNullOrEmpty()) {
- bo.lockList = mutableListOf()
- lockList.forEachIndexed { index, s ->
- if (s.isNullOrEmpty()) {
- LogUtil.w("Lock nfc is null or empty")
- return@forEachIndexed
- }
- bo.lockList?.add(LockListBO(index + 1, s))
- }
- }
- }
- // TODO partList 待补充
- val jsonStr = Gson().toJson(bo)
- LogUtil.i("json : $jsonStr")
- return jsonStr
- }
- /**
- * 生成下空发工作票Json
- *
- * @param vo 工作票详情
- */
- fun generateEmptyTicketSendJson(): String {
- // 构造一个所有字段都为空/默认值的 WorkTicketSendBO
- val bo = WorkTicketSendBO(
- cardNo = "", // 空卡号
- effectiveTime = 0, // 默认有效时长
- password = "" // 空密码
- ).apply {
- // data 列表留空
- data = mutableListOf()
- // lockList 留空(如果字段非空,再设置为 emptyList())
- lockList = mutableListOf()
- }
- // 转成 JSON 并返回
- val jsonStr = Gson().toJson(bo)
- LogUtil.i("generateEmptyTicketJson: $jsonStr")
- return jsonStr
- }
- fun handleRsp(
- bleBean: BleBean,
- byteArray: ByteArray,
- isNeedLoading: Boolean = false,
- prepareDoneCallBack: ((Boolean, BleBean?) -> Unit)?
- ) {
- // TODO Token校验
- // val len = byteArray[2].toInt()
- // val token = byteArray.copyOfRange(len + 7, len + 11)
- // if (token.contentEquals(bleBean.token)) {
- // LogUtil.i("Token is right")
- // } else {
- // LogUtil.e("Token is wrong")
- // }
- when {
- // 获取令牌
- byteArray.startsWith(BleConst.RSP_GET_TOKEN) -> BleCmdManager.handleToken(
- bleBean.bleDevice, byteArray
- ) { isSuccess ->
- if (isSuccess) {
- prepareDoneCallBack?.invoke(true, bleBean)
- }
- }
- // 工作模式切换
- byteArray.startsWith(BleConst.RSP_SWITCH_MODE) -> {
- handleSwitchModeResult(byteArray, isNeedLoading) { res, job ->
- sendEventMsg(
- MsgEvent(
- MSG_EVENT_SWITCH_MODE, SwitchModeMsg(job.toInt(), res.toInt(), bleBean)
- )
- )
- }
- }
- // 工作票下发
- byteArray.startsWith(BleConst.RSP_SEND_WORK_TICKET) -> handleWorkTicketResult(
- bleBean, byteArray, isNeedLoading
- )
- // 获取设备当前状态
- byteArray.startsWith(BleConst.RSP_CURRENT_STATUS) -> BleCmdManager.handleCurrentStatus(
- byteArray
- ) {
- sendEventMsg(MsgEvent(MSG_EVENT_CURRENT_MODE, CurrentModeMsg(bleBean, it)))
- }
- // 获取设备工作票完成情况
- byteArray.startsWith(BleConst.RSP_WORK_TICKET_RESULT) && byteArray[3] == 0x02.toByte() -> handleTicketStatus(
- bleBean.bleDevice, byteArray, isNeedLoading
- )
- byteArray.startsWith(BleConst.RSP_POWER_STATUS) -> {
- val power = byteArray[4].toInt()
- ModBusController.getKeyByMac(bleBean.bleDevice.mac)?.power = power
- if (power < 50) {//如果电量小于50就打开仓位充电
- ModBusController.controlKeyCharge(true, bleBean.bleDevice.mac) {
- LogUtil.i("钥匙: ${bleBean.bleDevice.mac} 开始充电")
- }
- }
- }
- }
- }
- /**
- * 工作模式切换结果
- * job : 0x01:工作模式 0x02:待机模式
- * res : 0x01:成功 0x02:失败
- */
- private fun handleSwitchModeResult(
- byteArray: ByteArray,
- isNeedLoading: Boolean = false,
- callBack: ((Byte, Byte) -> Unit)? = null
- ) {
- BleCmdManager.handleSwitchModeResult(byteArray) { job, res ->
- if (res == 0x01.toByte() && job == 0x01.toByte()) {
- LogUtil.i("切换工作模式成功")
- if (isNeedLoading) sendEventMsg(
- MsgEvent(
- MSG_EVENT_LOADING, LoadingMsg(false, "切换工作模式成功", null)
- )
- )
- } else if (res == 0x01.toByte() && job == 0x02.toByte()) {
- LogUtil.i("切换待机模式成功")
- if (isNeedLoading) sendEventMsg(
- MsgEvent(
- MSG_EVENT_LOADING, LoadingMsg(false, "切换待机模式成功", null)
- )
- )
- } else {
- LogUtil.e("切换模式失败 : ${job.toInt()} - ${res.toInt()}")
- if (isNeedLoading) sendEventMsg(
- MsgEvent(
- MSG_EVENT_LOADING, LoadingMsg(false, null, null)
- )
- )
- }
- callBack?.invoke(res, job)
- }
- }
- /**
- * 工作票下发结果
- * res:0x00:成功 0x01:失败 0x02:传输超时 0x0D:当前IDX超出范围 0x0E:当前数据CRC校验失败 0x14:JSON结构错误 0x63:未知错误
- */
- private fun handleWorkTicketResult(
- bleBean: BleBean, byteArray: ByteArray, isNeedLoading: Boolean = false
- ) {
- BleCmdManager.handleWorkTicketResult(bleBean, byteArray) { isSuccess, rst ->
- if (isNeedLoading) sendEventMsg(
- MsgEvent(
- MSG_EVENT_LOADING, LoadingMsg(false, null, null)
- )
- )
- if (isSuccess) {
- // 下发完毕,切换工作模式
- LogUtil.i("工作票下发完毕")
- if (isNeedLoading) sendEventMsg(
- MsgEvent(
- MSG_EVENT_LOADING, LoadingMsg(true, "切换钥匙为工作模式", null)
- )
- )
- Executor.delayOnIO(800) {
- //切换到工作模式
- switchWorkMode(bleBean.bleDevice, isNeedLoading)
- }
- } else {
- sendLoadingEventMsg(null, false)
- if (bleBean.retryCount < 3) {
- Executor.delayOnMain(500) {
- bleBean.retryCount++
- sendLoadingEventMsg(MyApplication.instance!!.getString(R.string.start_to_send_ticket))
- sendTicketWithRetry(bleBean.ticketSend!!, bleBean.bleDevice, isNeedLoading)
- }
- } else {
- ToastUtils.tip(R.string.send_ticket_fail)
- LogUtil.e("Send ticket fail")
- ModBusController.getKeyByMac(bleBean.bleDevice.mac)?.let { itKey ->
- mDeviceTakeList.removeIf { it.deviceType == DEVICE_TYPE_KEY && it.nfc == itKey.rfid }
- }
- }
- }
- }
- }
- /**
- * 获取当前钥匙的状态
- */
- fun getCurrentStatus(
- from: Int,
- bleDevice: BleDevice,
- retryCount: Int = 0,
- timeoutCallBack: ((Boolean) -> Unit)? = null
- ) {
- LogUtil.i("getCurrentStatus - ${bleDevice.mac} - from : $from")
- var isTimeout = true
- // 加1秒防止早于onWriteFailure开始处理导致多次处理
- Executor.delayOnMain((BleUtil.OPERATE_TIMEOUT + 1).toLong()) {
- if (isTimeout) {
- LogUtil.e("getCurrentStatus timeout : mac = ${bleDevice.mac}, retryCount = $retryCount")
- if (retryCount > 0) {
- Executor.delayOnMain(1000) {
- getCurrentStatus(from, bleDevice, retryCount - 1, timeoutCallBack)
- }
- } else {
- ModBusController.getKeyByMac(bleDevice.mac)?.rfid?.let {
- addExceptionKey(it)
- timeoutCallBack?.invoke(true)
- }
- }
- }
- }
- BleCmdManager.getCurrentStatus(bleDevice, object : CustomBleWriteCallback() {
- override fun onWriteSuccess(current: Int, total: Int, justWrite: ByteArray?) {
- LogUtil.i("getCurrentStatus success : ${bleDevice.mac}")
- isTimeout = false
- timeoutCallBack?.invoke(false)
- }
- override fun onWriteFailure(exception: BleException?) {
- LogUtil.i("getCurrentStatus fail : ${bleDevice.mac}")
- isTimeout = false
- Executor.delayOnMain(1000) {
- getCurrentStatus(from, bleDevice, timeoutCallBack = timeoutCallBack)
- }
- }
- })
- }
- /**
- * 获取电池电量
- */
- fun getBatteryPower(bleDevice: BleDevice) {
- LogUtil.i("获取电池电量:${bleDevice.mac}")
- BleCmdManager.getPower(bleDevice.mac, object : CustomBleWriteCallback() {
- override fun onWriteSuccess(p0: Int, p1: Int, p2: ByteArray?) {
- LogUtil.i("发送获取电池电量命令成功:${bleDevice.mac}")
- }
- override fun onWriteFailure(p0: BleException?) {
- ThreadUtils.runOnIODelayed(500) {
- LogUtil.i("发送获取电池电量命令失败:${bleDevice.mac}")
- getBatteryPower(bleDevice)
- }
- }
- })
- }
- /**
- * 切换工作模式
- */
- private fun switchWorkMode(bleDevice: BleDevice, isNeedLoading: Boolean = false) {
- LogUtil.i("switchWorkMode - ${bleDevice.mac}")
- BleCmdManager.switchMode(STATUS_WORK, bleDevice, object : CustomBleWriteCallback() {
- override fun onWriteSuccess(current: Int, total: Int, justWrite: ByteArray?) {
- LogUtil.i("switch mode work success : ${bleDevice.mac}")
- }
- override fun onWriteFailure(exception: BleException?) {
- LogUtil.e("switch mode work fail : ${exception?.code} - ${exception?.description}")
- Executor.delayOnMain(500) {
- switchWorkMode(bleDevice, isNeedLoading)
- }
- }
- })
- }
- /**
- * 处理工作票完成情况
- */
- private fun handleTicketStatus(
- bleDevice: BleDevice, byteArray: ByteArray, isNeedLoading: Boolean = false
- ) {
- BleCmdManager.handleTicketStatus(bleDevice, byteArray) { ticketJson ->
- if (ticketJson.isNullOrEmpty()) {
- return@handleTicketStatus
- }
- if (isNeedLoading) sendEventMsg(
- MsgEvent(
- MSG_EVENT_LOADING, LoadingMsg(false, "工作票完成状态读取完成", null)
- )
- )
- LogUtil.i("Get ticket status complete : ${bleDevice.mac}")
- // TD:Ticket Done
- if (isNeedLoading) sendEventMsg(
- MsgEvent(
- MSG_EVENT_LOADING, LoadingMsg(false, "TD$ticketJson}", true)
- )
- )
- val workTicketGetBO = try {
- Gson().fromJson(ticketJson, WorkTicketGetBO::class.java)
- } catch (e: Exception) {
- null
- }
- if (workTicketGetBO == null) {
- ToastUtils.tip(R.string.ticket_data_error)
- return@handleTicketStatus
- }
- // 判断workTicketGetBO里是否有未完成的
- ThreadUtils.runOnIO {
- val finishedStatus = workTicketGetBO.hasFinished()
- LogUtil.i("作业票结束情况:${finishedStatus}")
- if (finishedStatus.first) {
- Executor.delayOnMain(500) {
- handleKeyReturn(bleDevice, workTicketGetBO, finishedStatus.second)
- //检查钥匙是否代取,如果是的话给钥匙
- val keyBean = ModBusController.getKeyByMac(bleDevice.mac)
- mDeviceTakeList.find { it.deviceType == DEVICE_TYPE_KEY && it.nfc == keyBean?.rfid }
- ?.let { itKey ->
- sendLoadingEventMsg(
- MyApplication.instance?.applicationContext!!.getString(
- R.string.ble_connecting
- )
- )
- handleGiveKey(itKey)
- }
- }
- } else {
- // 当前策略:作业票未完成禁止归还钥匙
- withContext(Dispatchers.Main) {
- showKeyReturnDialog {
- sendLoadingEventMsg(null, false)
- ToastUtils.tip(R.string.continue_the_ticket)
- BleManager.getInstance().disconnect(bleDevice)
- deviceList.removeIf { device -> device.bleDevice.mac == bleDevice.mac }
- // 打开卡扣,防止初始化的时候选择不处理钥匙导致无法使用
- val dock = ModBusController.getDockByKeyMac(bleDevice.mac)
- val keyBean = dock?.getKeyList()?.find { it.mac == bleDevice.mac }
- keyBean?.let {
- ModBusController.controlKeyBuckle(true, keyBean.isLeft, dock.addr)
- }
- }
- }
- }
- }
- }
- }
- /**
- * ticketFinished主要是后端的作业票是否已经结束,结束了,就直接修改状态就好了
- */
- private fun handleKeyReturn(
- bleDevice: BleDevice, workTicketGetBO: WorkTicketGetBO?, ticketFinished: Boolean
- ) {
- val dock = ModBusController.getDockByKeyMac(bleDevice.mac)
- val keyBean = dock?.getKeyList()?.find { it.mac == bleDevice.mac }
- keyBean?.let {
- ModBusController.controlKeyBuckle(false, keyBean.isLeft, dock.addr)
- }
- if (ticketFinished) {
- mDeviceTakeList.removeIf { it.nfc == keyBean?.rfid }
- switchReadyMode(bleDevice)
- } else {
- // 上报隔离点状态
- val keyNfc = ModBusController.getKeyByMac(bleDevice.mac)?.rfid ?: "key rfid lost"
- workTicketGetBO?.data?.forEach { data ->
- val updateList = mutableListOf<LockPointUpdateReqVO>()
- data.dataList?.forEach { dataListDTO ->
- data.taskCode?.toLong()?.let {
- SPUtils.returnKey(it)
- }
- val updateVO = LockPointUpdateReqVO(
- data.taskCode?.toLong(),
- dataListDTO.infoRfidNo,
- dataListDTO.equipRfidNo,
- keyNfc,
- dataListDTO.target,
- dataListDTO.status
- )
- updateList.add(updateVO)
- }
- sendLoadingEventMsg(null, false)
- if (CAN_RETURN) {
- // 上报点位钥匙绑定
- NetApi.updateLockPointBatch(updateList) { isSuccess, msg, code ->
- LogUtil.i("还锁操作:${isSuccess},${msg},${code}")
- if (isSuccess) {
- // 上报钥匙归还
- NetApi.updateKeyReturn(
- data.taskCode?.toLong()!!,
- keyNfc!!,
- MyApplication.instance!!.serialNo()
- ) { isSuccess, msg, code ->
- if (!isSuccess && msg != MyApplication.instance?.applicationContext!!.getString(
- R.string.ticket_lost
- )
- ) {
- SPUtils.saveUpdateKeyReturn(
- MyApplication.instance!!,
- UpdateKeyReturnBO(data.taskCode?.toLong()!!, keyNfc!!)
- )
- if (msg == MyApplication.instance?.applicationContext!!.getString(
- R.string.ticket_lost
- )
- ) {
- sendEventMsg(
- MsgEvent(
- MsgEventConstants.MSG_EVENT_TICKET_FINISHED, null
- )
- )
- }
- ToastUtils.tip(R.string.key_return_success)
- } else {
- ToastUtils.tip(R.string.key_return_success)
- }
- }
- data.taskCode?.toLong()?.let {
- sendEventMsg(
- MsgEvent(
- MSG_EVENT_UPDATE_TICKET_PROGRESS,
- UpdateTicketProgressMsg(it)
- )
- )
- }
- // 确认归还,切换为待机模式
- switchReadyMode(bleDevice)
- } else {
- ThreadUtils.runOnMain {
- // 当前策略:作业票未完成禁止归还钥匙
- showKeyReturnDialog {
- sendLoadingEventMsg(null, false)
- ToastUtils.tip(R.string.continue_the_ticket)
- BleManager.getInstance().disconnect(bleDevice)
- deviceList.removeIf { device -> device.bleDevice.mac == bleDevice.mac }
- // 打开卡扣,防止初始化的时候选择不处理钥匙导致无法使用
- if (workTicketGetBO.data?.all { it.dataList?.all { it.closed == 1 } == true } == true) {
- workTicketGetBO.data?.firstOrNull()?.taskCode?.toLong()
- ?.let {
- checkStepAndTicketDetailThenSendTicket(
- it,
- bleDevice.mac
- )
- }
- } else {
- val dock = ModBusController.getDockByKeyMac(bleDevice.mac)
- val keyBean =
- dock?.getKeyList()?.find { it.mac == bleDevice.mac }
- keyBean?.let {
- ModBusController.controlKeyBuckle(
- true, keyBean.isLeft, dock.addr
- )
- }
- }
- }
- }
- SPUtils.clearUpdateKeyReturn(MyApplication.instance!!)
- SPUtils.clearUpdateLockPoint(MyApplication.instance!!)
- }
- }
- } else {
- SPUtils.saveUpdateLockPoint(MyApplication.instance!!, updateList)
- SPUtils.saveUpdateKeyReturn(
- MyApplication.instance!!,
- UpdateKeyReturnBO(data.taskCode?.toLong()!!, keyNfc!!)
- )
- // 保存待发数据,切换为待机模式
- switchReadyMode(bleDevice)
- }
- }
- }
- }
- /**
- * 处理虚拟钥匙取出,如果作业的全部点位已经上锁更新钥匙的状态使用
- */
- fun handleVirtualKeyGive(taskCode: Long, keyNfc: String, done: () -> Unit) {
- // 上报钥匙归还
- NetApi.updateKeyTake(taskCode, keyNfc, MyApplication.instance!!.serialNo()) { isSuccess ->
- if (isSuccess) {
- done()
- }
- }
- }
- /**
- * 处理虚拟钥匙归还,如果作业的全部点位已经上锁更新钥匙的状态使用
- */
- fun handleVirtualKeyReturn(taskCode: Long, keyNfc: String, done: () -> Unit) {
- // 上报钥匙归还
- NetApi.updateKeyReturn(
- taskCode, keyNfc, MyApplication.instance!!.serialNo()
- ) { isSuccess, msg, code ->
- if (!isSuccess && msg != MyApplication.instance?.applicationContext!!.getString(
- R.string.ticket_lost
- )
- ) {
- SPUtils.saveUpdateKeyReturn(
- MyApplication.instance!!, UpdateKeyReturnBO(taskCode, keyNfc)
- )
- if (msg == MyApplication.instance?.applicationContext!!.getString(
- R.string.ticket_lost
- )
- ) {
- sendEventMsg(
- MsgEvent(
- MsgEventConstants.MSG_EVENT_TICKET_FINISHED, null
- )
- )
- }
- } else {
- done()
- sendEventMsg(
- MsgEvent(
- MSG_EVENT_UPDATE_TICKET_PROGRESS, UpdateTicketProgressMsg(taskCode)
- )
- )
- }
- }
- }
- fun switchReadyMode(bleDevice: BleDevice) {
- BleCmdManager.switchMode(STATUS_READY, bleDevice, object : CustomBleWriteCallback() {
- override fun onWriteSuccess(current: Int, total: Int, justWrite: ByteArray?) {
- LogUtil.i("switch mode ready success : ${bleDevice.mac}")
- }
- override fun onWriteFailure(exception: BleException?) {
- LogUtil.e("switch mode ready fail : ${bleDevice.mac}")
- Executor.delayOnMain(300) {
- switchReadyMode(bleDevice)
- }
- }
- })
- }
- /**
- * 获取工作票完成情况
- */
- private fun getTicketStatus(
- bleDevice: BleDevice,
- isNeedLoading: Boolean = false,
- processCallback: ((Boolean) -> Unit)? = null
- ) {
- if (isNeedLoading) sendEventMsg(
- MsgEvent(
- MSG_EVENT_LOADING, LoadingMsg(true, "开始获取工作票", null)
- )
- )
- BleCmdManager.getTicketStatus(bleDevice, object : CustomBleWriteCallback() {
- override fun onWriteSuccess(current: Int, total: Int, justWrite: ByteArray?) {
- if (isNeedLoading) sendEventMsg(
- MsgEvent(
- MSG_EVENT_LOADING, LoadingMsg(false, "工作票获取成功", null)
- )
- )
- LogUtil.i("getTicketStatus success")
- }
- override fun onWriteFailure(exception: BleException?) {
- if (isNeedLoading) sendEventMsg(
- MsgEvent(
- MSG_EVENT_LOADING, LoadingMsg(false, "工作票获取失败", false)
- )
- )
- processCallback?.invoke(false)
- LogUtil.e("getTicketStatus fail")
- }
- })
- }
- /**
- * 添加待更新取出状态的设备
- */
- fun addDeviceTake(deviceType: Int, ticketId: Long, nfc: String?) {
- LogUtil.i("addDeviceTake : $deviceType - $ticketId - $nfc")
- mDeviceTakeList.removeIf { it.deviceType == deviceType && it.nfc == nfc }
- mDeviceTakeList.add(DeviceTakeUpdateBO(deviceType, ticketId, nfc!!))
- }
- fun removeDeviceTake(deviceType: Int, nfc: String?) {
- LogUtil.i("removeDeviceTake : $deviceType - $nfc")
- mDeviceTakeList.removeIf { it.deviceType == deviceType && it.nfc == nfc }
- }
- private fun handleDeviceTake(deviceTakeUpdateBO: DeviceTakeUpdateMsg, rfid: String? = null) {
- LogUtil.i("$deviceTakeUpdateBO")
- when (deviceTakeUpdateBO.deviceType) {
- // 钥匙
- 0 -> {
- mDeviceTakeList.find { it.deviceType == DEVICE_TYPE_KEY && it.nfc == deviceTakeUpdateBO.nfc }
- ?.let { info ->
- sendLoadingEventMsg(null, false)
- SPUtils.takeKey(info.ticketId)
- NetApi.updateKeyTake(
- info.ticketId, info.nfc, MyApplication.instance?.serialNo()!!
- ) { isSuccess ->
- if (isSuccess) {
- mDeviceTakeList.removeIf { it.deviceType == DEVICE_TYPE_KEY && it.nfc == info.nfc }
- sendEventMsg(
- MsgEvent(
- MSG_EVENT_UPDATE_TICKET_PROGRESS,
- UpdateTicketProgressMsg(info.ticketId)
- )
- )
- //钥匙取出之后重新再连一把钥匙待机
- ModBusController.getKeyByRfid(
- info.nfc
- )?.mac?.let {
- unregisterConnectListener(it)
- }
- //待机数不够就再连一把,但不能是原来那把
- NetApi.getMySelfState {
- if (it) {
- ModBusController.getKeyByRfid(
- info.nfc
- )?.mac?.let {
- val maxPowerMac = getMaxPowerKey().mac
- if (maxPowerMac != it) {
- connectExistsKey(listOf(it ?: ""))
- launchDisconnectJob(it ?: "")
- }
- }
- }
- }
- }
- }
- } ?: sendLoadingEventMsg(null, false)
- }
- // 挂锁
- 1 -> {
- mDeviceTakeList.find { it.deviceType == DEVICE_TYPE_LOCK && it.nfc == deviceTakeUpdateBO.nfc }
- ?.let { info ->
- NetApi.updateLockTake(
- mutableListOf(
- LockTakeUpdateReqVO(
- info.ticketId, info.nfc, MyApplication.instance?.serialNo()!!
- )
- )
- ) { isSuccess ->
- Executor.runOnMain {
- if (isSuccess == false) {
- LogUtil.e("Lock take report fail")
- ToastUtils.tip(R.string.lock_take_report_fail)
- SPUtils.saveTicketTakeLockException(info.ticketId)
- mDeviceTakeList.removeIf { it.deviceType == DEVICE_TYPE_LOCK && it.nfc == info.nfc }
- mDeviceTakeList.removeIf { it.deviceType == DEVICE_TYPE_KEY && it.ticketId == info.ticketId }
- sendLoadingEventMsg(null, false)
- return@runOnMain
- }
- // 检查是不是要发钥匙了
- mDeviceTakeList.removeIf { it.deviceType == DEVICE_TYPE_LOCK && it.nfc == info.nfc }
- // 检查当前工作票是否取完挂锁
- if (mDeviceTakeList.any { it.deviceType == DEVICE_TYPE_LOCK && it.ticketId == info.ticketId }) {
- LogUtil.i("Waiting all locks to take out")
- sendLoadingEventMsg(
- MyApplication.instance?.applicationContext?.getString(
- R.string.take_out_lock_tip,
- mDeviceTakeList.count { it.deviceType == DEVICE_TYPE_LOCK && it.ticketId == info.ticketId })
- )
- ToastUtils.tip(R.string.take_out_rest_locks)
- return@runOnMain
- } else {
- LogUtil.i("All locks are taken")
- sendLoadingEventMsg(null, false)
- }
- if (SPUtils.getTicketTakeLockException(info.ticketId)) {
- ToastUtils.tip(R.string.current_ticket_report_lock_take_exception_tip)
- return@runOnMain
- }
- // 检查有无当前工作票的钥匙
- mDeviceTakeList.find { it.deviceType == DEVICE_TYPE_KEY && it.ticketId == info.ticketId }
- ?.let { itKey ->
- sendLoadingEventMsg(
- MyApplication.instance?.applicationContext!!.getString(
- R.string.ble_connecting
- )
- )
- handleGiveKey(itKey)
- }
- }
- }
- }
- }
- }
- }
- /**
- * 分配钥匙
- */
- private fun handleGiveKey(deviceTakeUpdateBO: DeviceTakeUpdateBO) {
- getBleDeviceByMac(ModBusController.getKeyByRfid(deviceTakeUpdateBO.nfc)?.mac)?.let {
- getCurrentStatus(
- 2,
- getBleDeviceByMac(ModBusController.getKeyByRfid(deviceTakeUpdateBO.nfc)?.mac)!!.bleDevice
- ) {
- if (!it) {
- return@getCurrentStatus
- }
- LogUtil.w("handleGiveKey timeout")
- removeDeviceTake(DEVICE_TYPE_KEY, deviceTakeUpdateBO.nfc)
- checkEquipCount(0, true) { keyPair, lockMap ->
- if (keyPair == null) {
- ThreadUtils.runOnMain {
- val tipDialog = TipDialog(SIKCore.getApplication())
- tipDialog.setTip(
- SIKCore.getApplication().getString(R.string.key_take_error_tip)
- )
- tipDialog.setConfirmListener {
- tipDialog.dismiss()
- sendEventMsg(
- MsgEvent(
- MSG_EVENT_DEVICE_EXCEPTION,
- DeviceExceptionMsg(DEVICE_TYPE_KEY, deviceTakeUpdateBO.nfc)
- )
- )
- }
- tipDialog.show()
- }
- } else {
- addDeviceTake(
- DEVICE_TYPE_KEY, deviceTakeUpdateBO.ticketId, keyPair.second?.rfid!!
- )
- handleGiveKey(
- DeviceTakeUpdateBO(
- DEVICE_TYPE_KEY, deviceTakeUpdateBO.ticketId, keyPair.second?.rfid!!
- )
- )
- }
- }
- }
- } ?: run {
- ThreadUtils.runOnMain {
- val tipDialog = TipDialog(SIKCore.getApplication())
- tipDialog.setTip(SIKCore.getApplication().getString(R.string.key_take_error_tip))
- tipDialog.setConfirmListener {
- tipDialog.dismiss()
- sendEventMsg(
- MsgEvent(
- MSG_EVENT_DEVICE_EXCEPTION,
- DeviceExceptionMsg(DEVICE_TYPE_KEY, deviceTakeUpdateBO.nfc)
- )
- )
- }
- tipDialog.show()
- }
- }
- }
- /**
- * 根据当前模式进行处理
- */
- private fun handleCurrentMode(currentModeMsg: CurrentModeMsg) {
- when (currentModeMsg.mode) {
- // 工作模式
- 0x01.toByte() -> {
- // 读工作票
- getTicketStatusBusiness(currentModeMsg.bleBean.bleDevice.mac)
- }
- // 待机模式
- 0x02.toByte() -> {
- // 根据情况看是否需要下发工作票
- ModBusController.getKeyByMac(currentModeMsg.bleBean.bleDevice.mac)?.let { key ->
- // 判断是否有待取的钥匙
- val updateBo =
- mDeviceTakeList.find { it.deviceType == DEVICE_TYPE_KEY && key.rfid == it.nfc }
- if (mDeviceTakeList.any { it.deviceType == DEVICE_TYPE_LOCK && it.ticketId == updateBo?.ticketId }) {
- //todo 如果有钥匙待取但是对应的作业票的锁还有的,就不发
- return
- }
- updateBo?.let { itBO ->
- NetApi.getStepDetail(itBO.ticketId) {
- var step = 0
- it?.filter { it.stepStatus == "1" }
- ?.maxByOrNull { it.stepIndex!! }?.stepIndex?.let {
- step = it
- }
- NetApi.getTicketDetail(itBO.ticketId) { ticketDetail, _ ->
- if (ticketDetail == null) {
- return@getTicketDetail
- }
- val role = ticketDetail?.ticketUserVOList?.find {
- it.userId == SPUtils.getLoginUser(MyApplication.instance?.applicationContext!!)?.userId && it.userType == USER_TYPE_LOCKER
- }
- if (role == null) {
- ToastUtils.tip(R.string.you_are_not_locker_tip)
- return@getTicketDetail
- }
- if (step == 4) { // 上锁工作票
- sendTicketBusiness(
- true,
- currentModeMsg.bleBean.bleDevice.mac,
- ticketDetail,
- ticketDetail.ticketLockVOList?.filter { it.lockStatus != "2" }
- ?.map { it.lockNfc }?.toMutableList(),
- ActivityUtils.currentActivity() as BaseActivity<*>,
- true
- )
- } else if (step == 7) { // 解锁工作票
- sendTicketBusiness(
- false,
- currentModeMsg.bleBean.bleDevice.mac,
- ticketDetail,
- null,
- ActivityUtils.currentActivity() as BaseActivity<*>,
- true
- )
- }
- }
- }
- } ?: let {
- ModBusController.updateKeyReadyStatus(
- currentModeMsg.bleBean.bleDevice.mac, true, 4
- )
- sendLoadingEventMsg(null, false)
- //连上之后没有工作票要下发就断开 看是否还有设备等待连接,没有就不断开,有就让路,一般是初始化的时候
- launchDisconnectJob(currentModeMsg.bleBean.bleDevice.mac)
- NetApi.getMySelfState {
- if (it) {
- val maxPowerMac = getMaxPowerKey().mac
- if (maxPowerMac != currentModeMsg.bleBean.bleDevice.mac) {
- connectExistsKey(
- listOf(
- currentModeMsg.bleBean.bleDevice.mac ?: ""
- )
- )
- launchDisconnectJob(currentModeMsg.bleBean.bleDevice.mac ?: "")
- }
- } else {
- launchDisconnectJob(currentModeMsg.bleBean.bleDevice.mac ?: "")
- }
- }
- }
- }
- }
- // 故障模式
- 0x03.toByte() -> {
- // TODO 上报?
- ToastUtils.tip(
- "${currentModeMsg.bleBean.bleDevice.mac} : " + "${CommonUtils.getStr(R.string.key_is_in_failure_mode)}"
- )
- }
- }
- }
- /**
- * 检查步骤和作业票详情并且下发作业票
- */
- private fun checkStepAndTicketDetailThenSendTicket(ticketId: Long, mac: String) {
- NetApi.getStepDetail(ticketId) {
- var step = 0
- it?.filter { it.stepStatus == "1" }
- ?.maxByOrNull { it.stepIndex!! }?.stepIndex?.let {
- step = it
- }
- NetApi.getTicketDetail(ticketId) { ticketDetail, _ ->
- if (ticketDetail == null) {
- return@getTicketDetail
- }
- val role = ticketDetail?.ticketUserVOList?.find {
- it.userId == SPUtils.getLoginUser(MyApplication.instance?.applicationContext!!)?.userId && it.userType == USER_TYPE_LOCKER
- }
- if (role == null) {
- ToastUtils.tip(R.string.you_are_not_locker_tip)
- return@getTicketDetail
- }
- if (step == 4) { // 上锁工作票
- sendTicketBusiness(
- true,
- mac,
- ticketDetail,
- ticketDetail.ticketLockVOList?.filter { it.lockStatus != "2" }
- ?.map { it.lockNfc }?.toMutableList(),
- ActivityUtils.currentActivity() as BaseActivity<*>,
- true
- )
- } else if (step == 7) { // 解锁工作票
- sendTicketBusiness(
- false,
- mac,
- ticketDetail,
- null,
- ActivityUtils.currentActivity() as BaseActivity<*>,
- true
- )
- }
- }
- }
- }
- fun submitKeyData(context: Context) {
- if (!CAN_RETURN) return
- val updateList = SPUtils.getUpdateLockPoint(context)
- if (updateList.isNotEmpty()) {
- NetApi.updateLockPointBatch(updateList) { isSuccess, msg, code ->
- LogUtil.i("submitKeyData还锁操作:${isSuccess},${msg},${code}")
- if (isSuccess || code == 500) {
- SPUtils.clearUpdateLockPoint(context)
- SPUtils.clearUpdateKeyReturn(context)
- }
- }
- }
- val returnList =
- SPUtils.getUpdateKeyReturn(context).filter { it.keyNfc.isNotEmpty() }.toMutableList()
- if (returnList.isEmpty()) {
- return
- }
- val itemsToRemove = returnList.toList()
- var count = 0
- itemsToRemove.forEach { itData ->
- NetApi.updateKeyReturn(
- itData.ticketId, itData.keyNfc, context.serialNo()
- ) { isSuccess, msg, code ->
- count++
- if (isSuccess || msg == MyApplication.instance?.applicationContext!!.getString(
- R.string.ticket_lost
- )
- ) {
- returnList.remove(itData)
- getBleBeanByRfid(itData.keyNfc)?.bleDevice?.let {
- switchReadyMode(it)
- }
- if (msg == MyApplication.instance?.applicationContext!!.getString(
- R.string.ticket_lost
- )
- ) {
- sendEventMsg(
- MsgEvent(
- MsgEventConstants.MSG_EVENT_TICKET_FINISHED, null
- )
- )
- }
- }
- if (count == itemsToRemove.size) {
- if (returnList.isEmpty()) {
- SPUtils.clearUpdateKeyReturn(context)
- } else {
- returnList.forEach {
- SPUtils.saveUpdateKeyReturn(context, it)
- }
- }
- }
- }
- }
- }
- fun sendLoadingEventMsg(str: String?, isShow: Boolean = true) {
- sendEventMsg(MsgEvent(MSG_EVENT_LOADING, LoadingMsg(isShow, str, false)))
- }
- fun logout(context: Context) {
- reConnectKey()
- NetApi.logout()
- // 关所有有设备的卡扣
- dockList.filter { it.type == DOCK_TYPE_LOCK || it.type == DOCK_TYPE_PORTABLE }
- .forEach { dockBean ->
- val hasLockIdxList =
- dockBean.getLockList().filter { it.isExist }.map { it.idx } as MutableList<Int>
- val noLockIdxList =
- dockBean.getLockList().filter { !it.isExist }.map { it.idx } as MutableList<Int>
- ModBusController.controlLockBuckle(false, dockBean.addr, hasLockIdxList)
- ModBusController.controlLockBuckle(true, dockBean.addr, noLockIdxList)
- }
- dockList.filter { it.type == DOCK_TYPE_KEY || it.type == DOCK_TYPE_PORTABLE }
- .forEach { dockBean ->
- dockBean.getKeyList().forEach { key ->
- if (key.isExist) {
- NetApi.getKeyInfo(key.rfid.toString()) {
- if (it != null && !it.macAddress.isNullOrEmpty()) {
- ModBusController.updateKeyMac(
- dockBean.addr, key.isLeft, it.macAddress
- )
- } else {
- ModBusController.controlKeyBuckle(
- true, key.isLeft, dockBean.addr
- )
- }
- }
- } else {
- ModBusController.controlKeyBuckle(true, key.isLeft, dockBean.addr)
- }
- }
- }
- launchDisconnectAllJob()
- sendLoadingEventMsg(null, false)
- context.startActivity(Intent(context, LoginActivity::class.java).apply {
- flags = Intent.FLAG_ACTIVITY_NEW_TASK
- })
- }
- /**
- * 钥匙重新连接,清除内部作业票,清除所有代取设备重新分配
- */
- private fun reConnectKey() {
- val keyList = mDeviceTakeList.filter { it.deviceType == DEVICE_TYPE_KEY }
- // 不拿的设备不归你,下次登录重新按需分配
- // 尽早clear,防止触发handleCurrentMode导致重新下发作业票
- mDeviceTakeList.clear()
- // 连接后直接切换待机模式,让钥匙作业票失效并且重新准备完毕
- keyList.forEach {
- val mac = ModBusController.getKeyByRfid(it.nfc)?.mac
- if (mac == null) {
- NetApi.getKeyInfo(it.nfc) { keyInfo ->
- keyInfo?.macAddress?.let { itMac ->
- registerConnectListener(itMac) { isDone, bleBean ->
- if (isDone && bleBean != null) {
- switchReadyMode(bleBean.bleDevice)
- }
- }
- }
- }
- } else {
- registerConnectListener(mac) { isDone, bleBean ->
- if (isDone && bleBean != null) {
- switchReadyMode(bleBean.bleDevice)
- }
- }
- }
- }
- }
- /**
- * 强制使用setValue,防止postValue造成数据丢失
- */
- fun sendEventMsg(msgEvent: MsgEvent) {
- Executor.runOnMain {
- mEventBus.value = msgEvent
- }
- }
- fun addExceptionKey(rfid: String) {
- LogUtil.w("addExceptionKey: $rfid")
- if (mExceptionKeyList.contains(rfid)) {
- return
- }
- mExceptionKeyList.add(rfid)
- }
- fun removeExceptionKey(key: String) {
- LogUtil.i("removeExceptionKey: $key")
- mExceptionKeyList.remove(key)
- }
- }
|