| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870 |
- package com.grkj.iscs
- import android.bluetooth.BluetoothGatt
- import android.os.Build
- import android.util.Log
- import androidx.appcompat.app.AppCompatActivity
- 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.base.BaseActivity
- import com.grkj.iscs.ble.BleBean
- import com.grkj.iscs.ble.BleCmdManager
- import com.grkj.iscs.ble.BleConst
- import com.grkj.iscs.ble.BleConst.REQ_WORK_TICKET_RESULT_PART
- import com.grkj.iscs.ble.BleConst.STATUS_READY
- import com.grkj.iscs.ble.BleConst.STATUS_WORK
- import com.grkj.iscs.ble.BleUtil
- import com.grkj.iscs.ble.CustomBleGattCallback
- import com.grkj.iscs.ble.CustomBleIndicateCallback
- import com.grkj.iscs.ble.CustomBleScanCallback
- import com.grkj.iscs.ble.CustomBleWriteCallback
- import com.grkj.iscs.dialog.TipDialog
- import com.grkj.iscs.extentions.removeLeadingZeros
- import com.grkj.iscs.extentions.serialNo
- import com.grkj.iscs.extentions.startsWith
- import com.grkj.iscs.extentions.toByteArray
- import com.grkj.iscs.extentions.toHexStrings
- import com.grkj.iscs.modbus.DockBean
- import com.grkj.iscs.modbus.ModBusController
- import com.grkj.iscs.model.Constants
- import com.grkj.iscs.model.Constants.PERMISSION_REQUEST_CODE
- import com.grkj.iscs.model.DeviceConst.DEVICE_TYPE_CARD
- import com.grkj.iscs.model.DeviceConst.DEVICE_TYPE_FINGERPRINT
- import com.grkj.iscs.model.DeviceConst.DEVICE_TYPE_KEY
- import com.grkj.iscs.model.DeviceConst.DEVICE_TYPE_LOCK
- import com.grkj.iscs.model.DeviceConst.DOCK_TYPE_ELEC_LOCK_BOARD
- import com.grkj.iscs.model.DeviceConst.DOCK_TYPE_KEY
- import com.grkj.iscs.model.DeviceConst.DOCK_TYPE_LOCK
- import com.grkj.iscs.model.DeviceConst.DOCK_TYPE_PORTABLE
- import com.grkj.iscs.model.bo.WorkTicketGetBO
- import com.grkj.iscs.model.bo.WorkTicketSendBO
- import com.grkj.iscs.model.vo.ticket.LockPointUpdateReqVO
- import com.grkj.iscs.model.vo.ticket.TicketDetailRespVO
- import com.grkj.iscs.presentation.PresentationManager
- import com.grkj.iscs.util.ActivityUtils
- import com.grkj.iscs.util.CommonUtils
- import com.grkj.iscs.util.Executor
- import com.grkj.iscs.util.NetApi
- import com.grkj.iscs.util.SPUtils
- import com.grkj.iscs.util.ToastUtils
- import com.grkj.iscs.util.log.LogUtil
- import pub.devrel.easypermissions.AfterPermissionGranted
- /**
- * 业务层管理
- */
- object BusinessManager {
- var NEED_AUTH = true
- // 归还设备是否需要登录及角色验证
- private var CAN_RETURN = true
- get() {
- // TODO 临时注掉,方便调试
- val loginUser = SPUtils.getLoginUser(MyApplication.instance!!.applicationContext!!)
- return (NEED_AUTH && loginUser != null) || !NEED_AUTH
- }
- /****************************************** ModBus ******************************************/
- fun connectDock(isNeedInit: Boolean = false) {
- // 暂定100上限
- // TODO demo为了快用3个
- ModBusController.setSlaveCount(3)
- ModBusController.interruptReadTrashBinStatus(false)
- ModBusController.start(MyApplication.instance!!.applicationContext)
- // ModBusController.unregisterListener(MyApplication.instance!!.applicationContext)
- if (isNeedInit) {
- ModBusController.initDevicesStatus()
- }
- }
- fun disconnectDock() {
- ModBusController.stop()
- }
- class DeviceListener(
- val key: Any,
- val callBack: (DockBean) -> Unit
- )
- 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()
- }
- }
- }
- /**
- * 总的监听,做预处理,其余的所有监听均使用本监听处理后的数据,只允许调用一次
- */
- fun registerMainListener() {
- ModBusController.registerStatusListener(this) { res ->
- LogUtil.i("设备状态:${(res as List<ByteArray>).map { it.toHexStrings() }}")
- res.forEach { bytes ->
- val dockBean = ModBusController.updateStatus(bytes) ?: return@forEach
- // if (!CAN_RETURN) {
- // return@forEach
- // }
- when (dockBean.type) {
- DOCK_TYPE_KEY -> {
- dockBean.deviceList.forEach { keyBean ->
- if (keyBean.isExist) {
- // 放回钥匙,读取rfid
- ModBusController.readKeyRfid(dockBean.addr.toInt() - 1, if ((keyBean as DockBean.KeyBean).isLeft) 0 else 1) { isLeft, res ->
- val rfid = res.copyOfRange(3, 11).toHexStrings(false).removeLeadingZeros()
- ModBusController.updateKeyRfid(dockBean.addr.toInt(), keyBean.isLeft, rfid)
- if (PresentationManager.mConfigKeyList.any { it.rfid == rfid }) {
- val mac = PresentationManager.mConfigKeyList.find { it.rfid == rfid }?.keyMac
- ModBusController.updateKeyMac(dockBean.addr.toInt(), keyBean.isLeft, mac!!)
- }
- // NetApi.getKeyInfo(rfid) {
- // if (it != null && !it.macAddress.isNullOrEmpty()) {
- // ModBusController.updateKeyMac(dockBean.addr.toInt(), keyBean.isLeft, it.macAddress)
- // showKeyReturnDialog(it.macAddress, isLeft, dockBean.addr.toInt())
- // } else {
- // ToastUtils.tip(R.string.get_key_info_fail)
- // }
- // }
- // TODO 蓝牙通信
- }
- // ModBusController.controlKeyBuckle(false, isLeft = true, dockBean.addr.toInt() - 1)
- }
- }
- }
- DOCK_TYPE_LOCK -> {
- dockBean.deviceList.forEach { lockBean ->
- if (lockBean.isExist) {
- ModBusController.readLockRfid(dockBean.addr.toInt() - 1, lockBean.idx) { res ->
- val rfid = res.copyOfRange(3, 11).toHexStrings(false).removeLeadingZeros()
- ModBusController.updateLockRfid(dockBean.addr.toInt(), lockBean.idx, rfid)
- // NetApi.getLockInfo(rfid) {
- // if (it != null) {
- // TODO 考虑快速拿取
- ModBusController.controlLockBuckle(false, dockBean.addr.toInt() - 1, lockBean.idx) { itRst ->
- if (itRst.isNotEmpty()) {
- // 上报锁具信息
- // NetApi.updateLockReturn(rfid, MyApplication.instance!!.serialNo()) {}
- }
- }
- // }
- // }
- }
- }
- }
- }
- DOCK_TYPE_ELEC_LOCK_BOARD -> {
- // TODO 占位
- }
- DOCK_TYPE_PORTABLE -> {
- // TODO 便携式待完善
- dockBean.deviceList.forEach { deviceBean ->
- if (deviceBean.isExist) {
- when (deviceBean.type) {
- DEVICE_TYPE_KEY -> {
- ModBusController.readKeyRfid(dockBean.addr.toInt() - 1, deviceBean.idx) { isLeft, res ->
- val rfid = res.copyOfRange(3, 11).toHexStrings(false).removeLeadingZeros()
- ModBusController.updateKeyRfid(dockBean.addr.toInt(), true, rfid)
- NetApi.getKeyInfo(rfid) {
- if (it != null && !it.macAddress.isNullOrEmpty()) {
- ModBusController.updateKeyMac(dockBean.addr.toInt(), isLeft, it.macAddress)
- showKeyReturnDialog(it.macAddress, isLeft, dockBean.addr.toInt())
- } else {
- ToastUtils.tip(R.string.get_key_info_fail)
- }
- }
- // TODO 蓝牙通信
- }
- // ModBusController.controlKeyBuckle(false, isLeft = true, dockBean.addr.toInt() - 1)
- }
- DEVICE_TYPE_LOCK -> {
- ModBusController.readLockRfid(dockBean.addr.toInt() - 1, deviceBean.idx) { res ->
- val rfid = res.copyOfRange(3, 11).toHexStrings(false).removeLeadingZeros()
- ModBusController.updateLockRfid(dockBean.addr.toInt(), deviceBean.idx, rfid)
- NetApi.getLockInfo(rfid) {
- if (it != null) {
- // TODO 考虑快速拿取
- ModBusController.controlLockBuckle(false, dockBean.addr.toInt() - 1, deviceBean.idx) { itRst ->
- if (itRst.isNotEmpty()) {
- // 上报锁具信息
- NetApi.updateLockReturn(rfid, MyApplication.instance!!.serialNo()) {}
- }
- }
- }
- }
- }
- }
- DEVICE_TYPE_CARD -> {
- ModBusController.readPortalCaseCardRfid(dockBean.addr.toInt() - 1) { res ->
- val rfid = res.copyOfRange(3, 11).toHexStrings(false).removeLeadingZeros()
- println("卡片RFID : $rfid")
- }
- }
- DEVICE_TYPE_FINGERPRINT -> {
- }
- }
- }
- }
- }
- }
- Executor.delayOnMain(200) {
- listeners.forEach { it.callBack(dockBean) }
- }
- }
- }
- }
- /**
- * 钥匙归还提示确认弹框
- */
- private fun showKeyReturnDialog(mac: String, isLeft: Boolean, slaveIdx: Int) {
- val dlg = TipDialog(MyApplication.instance!!.applicationContext)
- dlg.setTip(MyApplication.instance!!.getString(R.string.key_return_tip))
- dlg.setType(TipDialog.TYPE_CONFIRM)
- dlg.setConfirmListener {
- ModBusController.controlKeyBuckle(false, isLeft, slaveIdx)
- getTicketStatusBusiness(mac, ActivityUtils.currentActivity() as BaseActivity<*>) { b, s, rst ->
- (ActivityUtils.currentActivity() as BaseActivity<*>).handleLoading(b, s)
- }
- }
- }
- 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
- println("锁具底座卡扣状态 : $isLeftLock - $isRightLock")
- }
- 1 -> {
- val tempList = mutableListOf<Boolean>()
- for (i in 0..7) {
- tempList.add((res[4].toInt() shr i) and 0x1 == 1)
- }
- println("锁具底座卡扣1-8状态 : $tempList")
- }
- 2 -> {
- val lock9Status = (res[4].toInt() shr 0) and 0x1 == 1
- val lock10Status = (res[4].toInt() shr 1) and 0x1 == 1
- println("锁具底座卡扣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
- println("钥匙底座卡扣状态 : $isLeftLock - $isRightLock")
- }
- 1 -> {
- val tempList = mutableListOf<Boolean>()
- for (i in 0..7) {
- tempList.add((res[4].toInt() shr i) and 0x1 == 1)
- }
- println("锁具底座卡扣1-8状态 : $tempList")
- }
- 2 -> {
- val lock9Status = (res[4].toInt() shr 0) and 0x1 == 1
- val lock10Status = (res[4].toInt() shr 1) and 0x1 == 1
- println("锁具底座卡扣9、10状态 : $lock9Status - $lock10Status")
- }
- }
- }
- }
- /**
- * 检查钥匙和锁具数量
- *
- * @param needLockCount 需要的锁具的数量(可能在别的机柜取过)
- */
- fun checkEquipCount(needLockCount: Int, callBack: (Pair<Byte, DockBean.KeyBean?>?, MutableMap<Byte, MutableList<DockBean.LockBean>>) -> Unit) {
- var lockCount = 0
- val lockMap = ModBusController.getLocks(needLockCount)
- lockMap.forEach { (_, rfidList) ->
- lockCount += rfidList.size
- }
- val key = ModBusController.getOneKey()
- var tipStr = ""
- println("checkEquipCount : $lockCount - $needLockCount")
- if (lockCount < needLockCount) {
- val msg = MyApplication.instance!!.applicationContext.resources.getString(R.string.lock_is_not_enough)
- LogUtil.w(msg)
- tipStr = msg
- }
- if (key == null) {
- val msg = MyApplication.instance!!.applicationContext.resources.getString(R.string.key_is_not_enough)
- LogUtil.w(msg)
- tipStr = if (tipStr.isEmpty()) {
- msg
- } else {
- tipStr + "\n" + msg
- }
- }
- if (tipStr.isNotEmpty()) {
- ToastUtils.tip(tipStr)
- }
- callBack.invoke(if (lockCount < needLockCount) null else key, lockMap)
- }
- /****************************************** 蓝牙 ******************************************/
- /******************************************蓝牙通用准备******************************************/
- fun prepareBle(
- mac: String,
- activity: AppCompatActivity,
- loadingCallBack: ((Boolean, String?, Boolean?) -> Unit)?,
- prepareDoneCallBack: ((Boolean, BleBean?) -> Unit)?
- ) {
- Executor.runOnMain {
- CommonUtils.checkBlePermission(activity) {
- doScanBle(mac, loadingCallBack, prepareDoneCallBack)
- }
- }
- }
- @AfterPermissionGranted(PERMISSION_REQUEST_CODE)
- fun doScanBle(mac: String, loadingCallBack: ((Boolean, String?, Boolean?) -> Unit)?, prepareDoneCallBack: ((Boolean, BleBean?) -> Unit)?) {
- LogUtil.d("扫描开始:$mac")
- loadingCallBack?.invoke(true, MyApplication.instance?.getString(R.string.start_scanning_for_devices), null)
- BleUtil.instance?.scan(object : CustomBleScanCallback() {
- override fun onPrompt(promptStr: String?) {
- BleManager.getInstance().enableBluetooth()
- }
- override fun onScanStarted(success: Boolean) {
- LogUtil.d("扫描开始:${success}")
- // BleUtil.instance?.deviceList?.clear()
- }
- override fun onScanning(bleDevice: BleDevice?) {
- bleDevice?.let {
- Log.d("doScanBle", "扫描到的设备:${it.mac}")
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
- if (!it.name.isNullOrBlank()) {
- // BleUtil.instance?.deviceList?.add(BleBean(it))
- } else {
- }
- } else {
- // BleUtil.instance?.deviceList?.add(BleBean(it))
- }
- }
- }
- override fun onScanFinished(scanResultList: MutableList<BleDevice>?) {
- loadingCallBack?.invoke(false, null, null)
- // if (BleUtil.instance?.deviceList?.isEmpty() == true) {
- // ToastUtils.tip(R.string.ble_no_device_found)
- // loadingCallBack?.invoke(false, null, false)
- // return
- // }
- // BleUtil.instance?.getBleDeviceByMac(mac)?.bleDevice?.let {
- // doConnect(it, loadingCallBack, prepareDoneCallBack)
- // }
- scanResultList?.find { it.mac == mac }?.let {
- doConnect(it, loadingCallBack, prepareDoneCallBack)
- }
- }
- })
- }
- /**
- * 连接蓝牙设备
- */
- fun doConnect(
- bleDevice: BleDevice,
- loadingCallBack: ((Boolean, String?, Boolean?) -> Unit)?,
- prepareDoneCallBack: ((Boolean, BleBean?) -> Unit)?
- ) {
- loadingCallBack?.invoke(true, CommonUtils.getStr(R.string.ble_connecting), null)
- BleManager.getInstance().disconnect(bleDevice)
- BleUtil.instance?.connectBySelect(bleDevice,
- object : CustomBleGattCallback() {
- override fun onPrompt(promptStr: String?) {
- loadingCallBack?.invoke(false, promptStr, false)
- }
- override fun onStartConnect() {}
- override fun onConnectFail(bleDevice: BleDevice?, exception: BleException?) {
- loadingCallBack?.invoke(false, CommonUtils.getStr(R.string.ble_connect_fail), false)
- prepareDoneCallBack?.invoke(false, null)
- }
- override fun onConnectSuccess(bleDevice: BleDevice?, gatt: BluetoothGatt?, status: Int) {
- loadingCallBack?.invoke(false, null, null)
- LogUtil.i("onConnectSuccess : $bleDevice")
- bleDevice?.let {
- val bleBean = BleBean(it)
- ToastUtils.tip(R.string.connect_success)
- BleUtil.instance?.deviceList?.add(bleBean)
- // 设置MTU
- Executor.delayOnMain(200) {
- BleUtil.instance?.setMtu(it)
- }
- // 监听
- Executor.delayOnMain(500) {
- indicate(bleBean, loadingCallBack, prepareDoneCallBack)
- }
- }
- }
- override fun onDisConnected(isActiveDisConnected: Boolean, device: BleDevice?, gatt: BluetoothGatt?, status: Int) {
- loadingCallBack?.invoke(false, null, false)
- ToastUtils.tip(CommonUtils.getStr(R.string.ble_disconnect))
- BleUtil.instance?.getBleDeviceByMac(device?.mac)?.let {
- BleUtil.instance?.deviceList?.remove(it)
- }
- }
- })
- }
- /**
- * 监听蓝牙设备
- */
- private fun indicate(
- bleBean: BleBean?,
- loadingCallBack: ((Boolean, String?, Boolean?) -> Unit)?,
- prepareDoneCallBack: ((Boolean, BleBean?) -> Unit)?
- ) {
- loadingCallBack?.invoke(true, MyApplication.instance?.getString(R.string.start_indicating), null)
- bleBean?.let {
- BleUtil.instance?.indicate(it.bleDevice, indicateCallback = object : CustomBleIndicateCallback() {
- override fun onPrompt(promptStr: String?) {
- LogUtil.i("监听onPrompt : $promptStr")
- }
- override fun onConnectPrompt(promptStr: String?) {
- LogUtil.i("监听onConnectPrompt : $promptStr")
- }
- override fun onDisConnectPrompt(promptStr: String?) {
- LogUtil.i("监听onDisConnectPrompt : $promptStr")
- }
- override fun onIndicateSuccess() {
- LogUtil.i("监听成功")
- // val testStr = "{\"cardNo\":\"80A8C0F4EA\",\"password\":\"12345678\",\"effectiveTime\":24,\"data\":[{\"taskCode\":\"202401020001\",\"taskId\":\"71b49baa49b343bc84d7e6b829ac1bdc\",\"codeId\":1,\"dataList\":[{\"dataId\":1,\"equipRfidNo\":\"049648B2E31690\",\"infoRfidNo\":\"04E3BCCA201290\",\"target\":1},{\"dataId\":2,\"equipRfidNo\":\"0405982414C563\",\"target\":0,\"prevId\":1}]},{\"taskCode\":\"202401020002\",\"taskId\":\"145b5a4cc38c41e19943f4c8b48d12b0\",\"codeId\":2,\"dataList\":[{\"dataId\":1,\"equipRfidNo\":\"045460F7F4F438\",\"infoRfidNo\":\"04BC6584C65009\",\"target\":1},{\"dataId\":2,\"equipRfidNo\":\"042B99E449E795\",\"target\":0,\"prevId\":1},{\"dataId\":3,\"equipRfidNo\":\"04A312EE848B62\",\"infoRfidNo\":\"04220E86831289\",\"target\":1,\"prevId\":2}]}],\"lockList\":[{\"lockId\":\"1\",\"rfid\":\"040E21443010E9\"},{\"lockId\":\"2\",\"rfid\":\"0457505E5861C2\"}]}"
- // sendTicket(testStr, it.bleDevice, loadingCallBack)
- getToken(bleBean, loadingCallBack, prepareDoneCallBack)
- }
- override fun onIndicateFailure(exception: BleException?) {
- loadingCallBack?.invoke(false, null, false)
- ToastUtils.tip(MyApplication.instance?.getString(R.string.indicate_fail))
- LogUtil.i("监听失败")
- prepareDoneCallBack?.invoke(false, null)
- }
- override fun onCharacteristicChanged(data: ByteArray?) {
- LogUtil.i("监听数据 : ${data?.toHexStrings()}")
- data?.let { itData ->
- handleRsp(it, itData, loadingCallBack)
- }
- }
- })
- }
- }
- /**
- * 获取蓝牙钥匙token
- */
- private fun getToken(
- bleBean: BleBean?,
- loadingCallBack: ((Boolean, String?, Boolean?) -> Unit)?,
- prepareDoneCallBack: ((Boolean, BleBean?) -> Unit)?
- ) {
- loadingCallBack?.invoke(true, MyApplication.instance?.getString(R.string.start_getting_token), null)
- bleBean?.let {
- BleCmdManager.getToken(it.bleDevice.mac, object : CustomBleWriteCallback() {
- override fun onWriteSuccess(current: Int, total: Int, justWrite: ByteArray?) {
- loadingCallBack?.invoke(false, MyApplication.instance?.getString(R.string.get_token_success), null)
- LogUtil.i("getToken success : ${bleBean.bleDevice.mac}")
- prepareDoneCallBack?.invoke(true, bleBean)
- }
- override fun onWriteFailure(exception: BleException?) {
- loadingCallBack?.invoke(false, MyApplication.instance?.getString(R.string.get_token_fail), false)
- LogUtil.e("getToken fail : ${bleBean.bleDevice.mac}")
- prepareDoneCallBack?.invoke(false, null)
- }
- })
- }
- }
- /******************************************蓝牙通用准备结束******************************************/
- /**
- * 下发工作票
- * TODO 演示demo专用
- * @param loadingCallBack 是否显示loading、提示信息、是否结束(true成功结束、false失败结束、null继续执行)
- */
- fun sendTicketBusiness(
- mac: String,
- activity: AppCompatActivity,
- loadingCallBack: ((Boolean, String?, Boolean?) -> Unit)?
- ) {
- // prepareBle(mac, activity, loadingCallBack) { done, bleBean ->
- // if (done) {
- // Executor.delayOnMain(500) {
- // TODO 蓝牙准备操作
- val bleBean = BleUtil.instance?.getBleDeviceByMac(mac)
- if (bleBean == null) {
- ToastUtils.tip(R.string.simple_key_is_not_connected)
- return
- }
- // 单bleBean json赋值
- bleBean?.ticketSend = PresentationManager.getSimpleTicketJson()
- bleBean?.ticketSend?.let { itJson ->
- sendTicket(itJson, bleBean.bleDevice, loadingCallBack)
- }
- // }
- // } else {
- // loadingCallBack?.invoke(false, null, false)
- // }
- // }
- }
- /**
- * 下发工作票
- */
- fun sendTicketBusiness(
- mac: String,
- ticketDetail: TicketDetailRespVO,
- activity: AppCompatActivity,
- loadingCallBack: ((Boolean, String?, Boolean?) -> Unit)?,
- ) {
- prepareBle(mac, activity, loadingCallBack) { done, bleBean ->
- if (done) {
- Executor.delayOnMain(500) {
- // 单bleBean json赋值
- bleBean?.ticketSend = generateTicketSendJson(ticketDetail)
- bleBean?.ticketSend?.let { itJson ->
- sendTicket(itJson, bleBean.bleDevice, loadingCallBack)
- }
- }
- } else {
- loadingCallBack?.invoke(false, null, false)
- }
- }
- }
- /**
- * 读取工作票完成情况
- */
- fun getTicketStatusBusiness(mac: String, activity: AppCompatActivity, loadingCallBack: ((Boolean, String?, Boolean?) -> Unit)?) {
- prepareBle(mac, activity, loadingCallBack) { done, bleBean ->
- if (done) {
- Executor.delayOnMain(500) {
- // // TODO 蓝牙准备操作
- // val bleBean = BleUtil.instance?.getBleDeviceByMac(mac)
- // if (bleBean == null) {
- // ToastUtils.tip(R.string.simple_key_is_not_connected)
- // return
- // }
- getTicketStatus(bleBean!!.bleDevice, loadingCallBack)
- }
- } else {
- loadingCallBack?.invoke(false, null, false)
- }
- }
- }
- private fun sendTicket(jsonStr: String, bleDevice: BleDevice, loadingCallBack: ((Boolean, String?, Boolean?) -> Unit)?) {
- val ctx = MyApplication.instance!!
- loadingCallBack?.invoke(true, ctx.getString(R.string.simple_start_send_ticket), null)
- BleCmdManager.sendWorkTicket(jsonStr, bleDevice = bleDevice, callback = object : CustomBleWriteCallback() {
- override fun onWriteSuccess(current: Int, total: Int, justWrite: ByteArray?) {
- println("sendTicket success")
- loadingCallBack?.invoke(true, ctx.getString(R.string.simple_sending_ticket), null)
- }
- override fun onWriteFailure(exception: BleException?) {
- LogUtil.e("sendTicket fail : ${bleDevice.mac}")
- loadingCallBack?.invoke(false, ctx.getString(R.string.simple_send_ticket_fail), null)
- }
- })
- }
- /**
- * 生成下发工作票Json
- *
- * @param vo 工作票详情
- */
- private fun generateTicketSendJson(vo: TicketDetailRespVO): String {
- // 用ticketStatus的"待上锁"进行判断
- val isLock = vo.ticketStatus == Constants.TICKET_STATUS_READY_TO_LOCK
- val bo = WorkTicketSendBO(
- cardNo = SPUtils.getLoginUser(MyApplication.instance!!.applicationContext)?.cardNfc,
- )
- CommonUtils.getDiffHours(vo.ticketEndTime)?.let {
- bo.effectiveTime = it
- }
- val dataBO = WorkTicketSendBO.DataBO(
- taskCode = vo.ticketCode,
- taskId = vo.ticketId.toString(),
- codeId = 1
- )
- val taskList = ArrayList<WorkTicketSendBO.DataBO.DataListBO>()
- vo.pointDetailVOList?.let { itList ->
- itList.forEach { pointVO ->
- val task = WorkTicketSendBO.DataBO.DataListBO(
- dataId = pointVO.pointId?.toInt(),
- equipRfidNo = pointVO.pointNfc,
- infoRfidNo = pointVO.pointName,
- target = if (isLock) 0 else 1
- )
- pointVO.prePointId?.let {
- task.prevId = it.toInt()
- }
- if (!isLock) {
- task.infoRfidNo = pointVO.lockId.toString()
- }
- // TODO partCode待补充
- taskList.add(task)
- }
- }
- dataBO.dataList = taskList
- bo.data = mutableListOf(dataBO)
- if (isLock) {
- bo.lockList = mutableListOf()
- }
- // TODO partList 待补充
- val jsonStr = Gson().toJson(bo)
- return jsonStr
- }
- fun handleRsp(bleBean: BleBean, byteArray: ByteArray, loadingCallBack: ((Boolean, String?, Boolean?) -> 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) -> handleToken(bleBean.bleDevice, byteArray)
- // 工作模式切换
- byteArray.startsWith(BleConst.RSP_SWITCH_MODE) -> handleSwitchModeResult(byteArray, loadingCallBack)
- // 工作票下发
- byteArray.startsWith(BleConst.RSP_SEND_WORK_TICKET) -> handleWorkTicketResult(bleBean, byteArray, loadingCallBack)
- // 获取设备工作票完成情况
- byteArray.startsWith(BleConst.RSP_WORK_TICKET_RESULT) && byteArray[3] == 0x02.toByte() ->
- handleTicketStatus(bleBean.bleDevice, byteArray, loadingCallBack)
- }
- }
- /**
- * 令牌处理
- */
- private fun handleToken(bleDevice: BleDevice, byteArray: ByteArray) {
- LogUtil.i("handleToken : ${byteArray.toHexStrings()}")
- BleUtil.instance?.getBleDeviceByMac(bleDevice.mac)?.let {
- it.token = byteArrayOf(byteArray[11], byteArray[12], byteArray[13], byteArray[14])
- println("Token 赋值 ${it.token?.toHexStrings()} : ${bleDevice.mac}")
- }
- }
- /**
- * 工作模式切换结果
- * job : 0x01:工作模式 0x02:待机模式
- * res : 0x01:成功 0x02:失败
- */
- private fun handleSwitchModeResult(byteArray: ByteArray, loadingCallBack: ((Boolean, String?, Boolean?) -> Unit)?) {
- LogUtil.i("handleSwitchModeResult : ${byteArray.toHexStrings()}")
- val ctx = MyApplication.instance!!
- val job = byteArray[4]
- val res = byteArray[5]
- loadingCallBack?.invoke(false, null, null)
- if (res == 0x01.toByte() && job == 0x01.toByte()) {
- loadingCallBack?.invoke(false, ctx.getString(R.string.simple_switch_work_mode_success), null)
- // TODO 切成工作模式断开,待机模式不断开
- BleManager.getInstance().disconnectAllDevice()
- } else if (res == 0x02.toByte() && job == 0x01.toByte()) {
- loadingCallBack?.invoke(false, ctx.getString(R.string.simple_switch_standby_mode_success), null)
- }
- }
- /**
- * 工作票下发结果
- * res:0x00:成功 0x01:失败 0x02:传输超时 0x0D:当前IDX超出范围 0x0E:当前数据CRC校验失败 0x14:JSON结构错误 0x63:未知错误
- */
- private fun handleWorkTicketResult(bleBean: BleBean, byteArray: ByteArray, loadingCallBack: ((Boolean, String?, Boolean?) -> Unit)?) {
- val ctx = MyApplication.instance!!
- LogUtil.i("handleWorkTicketResult : ${byteArray.toHexStrings()}")
- loadingCallBack?.invoke(false, null, null)
- val idx = byteArray[4] + byteArray[5]
- val total = byteArray[6] + byteArray[7]
- val res = byteArray[8]
- if (idx != total - 1) {
- if ((res == 0x00.toByte() || res == 0x02.toByte())) {
- // TODO 要判断res
- BleCmdManager.sendWorkTicket(
- BleUtil.instance?.getBleDeviceByMac(bleBean.bleDevice.mac)?.ticketSend!!,
- if (res == 0x00.toByte()) idx + 1 else idx,
- bleBean.bleDevice,
- object : CustomBleWriteCallback() {
- override fun onWriteSuccess(current: Int, total: Int, justWrite: ByteArray?) {}
- override fun onWriteFailure(exception: BleException?) {}
- })
- }
- } else {
- LogUtil.i("Work ticket is done")
- // 下发完毕,切换工作模式
- loadingCallBack?.invoke(true, ctx.getString(R.string.simple_switch_work_mode), null)
- BleCmdManager.switchMode(STATUS_WORK, bleBean.bleDevice, object : CustomBleWriteCallback() {
- override fun onWriteSuccess(current: Int, total: Int, justWrite: ByteArray?) {
- println("switch mode 1 success")}
- override fun onWriteFailure(exception: BleException?) {
- println("switch mode 1 fail")}
- })
- // 打开钥匙卡扣
- val keyBean = ModBusController.getKeyByMac(bleBean.bleDevice.mac)
- if (keyBean == null) {
- loadingCallBack?.invoke(false, ctx.getString(R.string.simple_key_not_found), false)
- ToastUtils.tip(R.string.simple_key_not_exists)
- } else {
- loadingCallBack?.invoke(false, null, true)
- val dock = ModBusController.getDockByKeyMac(bleBean.bleDevice.mac)
- ModBusController.controlKeyBuckle(true, keyBean.isLeft, dock?.addr!!.toInt() - 1)
- }
- }
- }
- /**
- * 处理工作票完成情况
- */
- private fun handleTicketStatus(bleDevice: BleDevice, byteArray: ByteArray, loadingCallBack: ((Boolean, String?, Boolean?) -> Unit)?) {
- // TODO 需要有超时重传机制
- LogUtil.i("handleTicketStatus : ${byteArray.toHexStrings()}")
- val ctx = MyApplication.instance!!
- val total = byteArray[4] + byteArray[5]
- val idx = byteArray[6] + byteArray[7]
- val crc = byteArray[8] + byteArray[9]
- val size = byteArray[10].toUByte() + byteArray[11].toUByte()
- println("工作票数据 : $total : $idx : $size")
- // 数据组装
- BleUtil.instance?.getBleDeviceByMac(bleDevice.mac)?.let {
- it.ticketStatus += byteArray.copyOfRange(12, 12 + size.toInt())
- }
- // TODO 缺少res处理
- if (idx != total - 1) {
- loadingCallBack?.invoke(true, ctx.getString(R.string.simple_get_ticket_part), null)
- getTicketStatusPart((idx + 1).toByteArray(), total.toByteArray(), byteArrayOf(0x01.toByte()), bleDevice, object : CustomBleWriteCallback() {
- override fun onWriteSuccess(current: Int, total: Int, justWrite: ByteArray?) {
- println("getTicketStatusPart success")
- }
- override fun onWriteFailure(exception: BleException?) {
- println("getTicketStatusPart fail")
- }
- })
- } else {
- loadingCallBack?.invoke(false, ctx.getString(R.string.simple_get_ticket_status_done), null)
- BleUtil.instance?.getBleDeviceByMac(bleDevice.mac)?.let {
- println("工作票完成接收 : ${String(it.ticketStatus)}")
- // TD:Ticket Done
- loadingCallBack?.invoke(false, "TD${String(it.ticketStatus)}", true)
- // TODO 清空ticket
- it.ticketStatus = byteArrayOf()
- // TODO 根据工作票完成情况,切换为待机模式
- BleCmdManager.switchMode(STATUS_READY, bleDevice, object : CustomBleWriteCallback() {
- override fun onWriteSuccess(current: Int, total: Int, justWrite: ByteArray?) {
- println("switch mode 1 success")}
- override fun onWriteFailure(exception: BleException?) {
- println("switch mode 1 fail")}
- })
- val dock = ModBusController.getDockByKeyMac(bleDevice.mac)
- val keyBean = dock?.getKeyList()?.find { it.mac == bleDevice.mac }
- keyBean?.let {
- ModBusController.controlKeyBuckle(false, keyBean.isLeft, dock.addr.toInt() - 1)
- }
- // 上报隔离点状态
- val workTicketGetBO = Gson().fromJson(String(it.ticketStatus), WorkTicketGetBO::class.java)
- val keyNfc = ModBusController.getKeyByMac(bleDevice.mac)?.rfid
- workTicketGetBO?.data?.forEach { data ->
- val updateList = mutableListOf<LockPointUpdateReqVO>()
- data.dataList?.forEach { dataListDTO ->
- val updateVO = LockPointUpdateReqVO(
- data.taskId?.toLong(),
- dataListDTO.infoRfidNo,
- dataListDTO.equipRfidNo,
- keyNfc!!,
- dataListDTO.target,
- dataListDTO.status
- )
- updateList.add(updateVO)
- }
- // 上报点位钥匙绑定
- // NetApi.updateLockPointBatch(updateList) { itRst ->
- // // TODO 上报结果
- // }
- // 上报钥匙归还
- // NetApi.updateKeyReturn(data.taskId?.toLong()!!, keyNfc!!, MyApplication.instance!!.serialNo()) {
- //
- // }
- }
- }
- }
- }
- /**
- * 获取工作票完成情况分包
- */
- private fun getTicketStatusPart(idx: ByteArray, total: ByteArray, res: ByteArray, bleDevice: BleDevice, callback: CustomBleWriteCallback?) {
- BleUtil.instance?.getBleDeviceByMac(bleDevice.mac)?.let {
- BleUtil.instance?.write(it.bleDevice, cmd = BleCmdManager.assembleData(it, REQ_WORK_TICKET_RESULT_PART + idx + total + res), writeCallback = callback)
- }
- }
- /**
- * 获取工作票完成情况
- */
- private fun getTicketStatus(bleDevice: BleDevice, loadingCallBack: ((Boolean, String?, Boolean?) -> Unit)?) {
- loadingCallBack?.invoke(true, MyApplication.instance?.getString(R.string.start_getting_ticket), null)
- BleCmdManager.getTicketStatus(bleDevice, object : CustomBleWriteCallback() {
- override fun onWriteSuccess(current: Int, total: Int, justWrite: ByteArray?) {
- loadingCallBack?.invoke(false, MyApplication.instance?.getString(R.string.get_ticket_success), null)
- println("getTicketStatus success")}
- override fun onWriteFailure(exception: BleException?) {
- loadingCallBack?.invoke(false, MyApplication.instance?.getString(R.string.get_ticket_fail), false)
- println("getTicketStatus fail")}
- })
- }
- }
|