| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- package com.grkj.iscs.modbus
- import android.content.Context
- import com.grkj.iscs.extentions.removeLeadingZeros
- import com.grkj.iscs.extentions.toHexStrings
- 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.util.Executor
- import com.grkj.iscs.util.log.LogUtil
- import java.util.concurrent.Executors
- /**
- * ModBus 主控板控制器
- */
- object ModBusController {
- /**
- * 底座列表
- */
- var dockList: MutableList<DockBean> = mutableListOf()
- private const val LISTENER_TYPE_STATUS = 3
- // 主控板管理器
- private var modBusManager: ModBusManager? = null
- private var slaveCount: Int = 0
- private val threadPool = Executors.newScheduledThreadPool(4)
- private val listeners = ArrayList<StatusListener>()
- // 是否中断读取状态
- private var interruptReadStatus: ArrayList<Boolean> = ArrayList()
- var shouldStopUpgrade = false
- fun setSlaveCount(count: Int) {
- modBusManager?.slaveCount = count
- slaveCount = count
- }
- class StatusListener(
- val key: Any,
- val listener: (Any) -> Unit,
- val type: Int
- )
- fun interruptReadTrashBinStatus(interrupt: Boolean) {
- interruptReadStatus.clear()
- interruptReadStatus.add(interrupt)
- }
- @ExperimentalUnsignedTypes
- fun start(ctx: Context) {
- modBusManager?.stop()
- PortManager.openCtrlBord(ctx)
- ?.let { pm ->
- return@let ModBusManager(slaveCount, pm, true)
- }
- // 间隔 1 秒读一遍桶的状态
- ?.repeatSendToAll(MBFrame.READ_STATUS, {
- interruptReadStatus
- }, { res ->
- // // Logger.d("ModbusController", "res: ${res.map { it.toHexString() }}")
- LogUtil.i("****************************************************************************")
- for (l in listeners) {
- if (l.type == LISTENER_TYPE_STATUS) {
- l.listener(res)
- }
- }
- // TODO 临时改成5s
- // }, 1000)
- }, 5000)
- ?.also {
- modBusManager = it
- Executor.runOnIO {
- // refreshAllowOpenDoorUnidentified(ctx, it)
- }
- }
- ?.start()
- }
- fun registerStatusListener(key: Any, listener: (Any) -> Unit) {
- listeners.add(StatusListener(key, listener, LISTENER_TYPE_STATUS))
- }
- fun unregisterListener(key: Any) {
- val it = listeners.iterator()
- while (it.hasNext()) {
- if (it.next().key == key) {
- it.remove()
- }
- }
- }
- fun stop() {
- modBusManager?.stop()
- }
- /*****************************************************************************************/
- /**
- * 初始化所有设备的状态
- */
- // TODO 通电后多久执行?App每次重启的执行是什么
- fun initDevicesStatus() {
- readDeviceType { res ->
- res.forEach { bytes ->
- if (bytes.size < 5) return@forEach
- // TODO 设备具体数据由0x0011寄存器提供
- updateDeviceType(bytes[0], bytes[4])
- val type = when (bytes[4]) {
- DOCK_TYPE_KEY -> "钥匙底座"
- DOCK_TYPE_LOCK -> "锁具底座"
- DOCK_TYPE_ELEC_LOCK_BOARD -> "电磁锁控制板"
- DOCK_TYPE_PORTABLE -> "便携式底座"
- else -> "未知"
- }
- LogUtil.i("initDevicesStatus 设备(${bytes[0].toInt()})类型:$type")
- }
- }
- Executor.delayOnMain({
- // TODO 待完善
- initLock() // TODO 打开所有无锁的卡扣、读取所有锁的RFID
- initKey() // TODO 打开所有无钥匙的卡扣、关闭所有钥匙灯光、读取所有钥匙的RFID
- // TODO 设置所有钥匙的模式
- // TODO 通过HTTP获取所有钥匙的Mac
- }, 3000)
- }
- /**
- * 初始化锁具——打开所有无锁的卡扣、读取RFID
- */
- private fun initLock() {
- LogUtil.i("initLock : $dockList")
- dockList.filter { it.type == DOCK_TYPE_LOCK }.forEach { dockBean ->
- val hasLockIdxList = dockBean.getLockList().filter { it.isExist }.map { it.idx }
- val noLockIdxList = dockBean.getLockList().filter { !it.isExist }.map { it.idx } as MutableList<Int>
- hasLockIdxList.forEach { idx ->
- readLockRfid(dockBean.addr.toInt() - 1, idx) { res ->
- val rfid = res.copyOfRange(3, 11).toHexStrings(false).removeLeadingZeros()
- LogUtil.i("初始化锁具 RFID : $rfid")
- updateLockRfid(dockBean.addr.toInt(), idx, rfid)
- }
- }
- controlLockBuckle(true, dockBean.addr.toInt() - 1, noLockIdxList)
- }
- }
- /**
- * 初始化钥匙——关闭所有钥匙灯光
- */
- private fun initKey() {
- LogUtil.i("initKey : $dockList")
- dockList.filter { it.type == DOCK_TYPE_KEY }.forEach { dockBean ->
- controlKeyLight(dockBean.addr.toInt() - 1, 2, 2)
- dockBean.getKeyList().forEach { key ->
- if (key.isExist) {
- LogUtil.i("initKey : ${dockBean.addr.toInt() - 1} : ${key.isLeft}")
- readKeyRfid(dockBean.addr.toInt() - 1, key.isLeft) { isLeft, res ->
- val rfid = res.copyOfRange(3, 11).toHexStrings(false).removeLeadingZeros()
- LogUtil.i("初始化钥匙 RFID : $rfid")
- updateKeyRfid(dockBean.addr.toInt(), isLeft, rfid)
- }
- } else {
- // TODO 关闭钥匙卡扣
- }
- }
- }
- }
- /**
- * 更新状态
- */
- fun updateStatus(byteArray: ByteArray): DockBean? {
- if (byteArray.isEmpty()) {
- return null
- }
- val dockB = dockList.find { it.addr == byteArray[0] }
- return dockB?.parseStatus(byteArray) ?: let {
- val temp = DockBean(byteArray[0], null, mutableListOf())
- dockList.add(temp)
- temp.parseStatus(byteArray)
- }
- }
- /**
- * 读取设备类型
- */
- fun readDeviceType(done: ((res: List<ByteArray>) -> Unit)? = null) {
- modBusManager?.sendToAll(MBFrame.READ_DEVICE_TYPE) { res ->
- done?.invoke(res)
- }
- }
- /**
- * 更新设备类型
- */
- fun updateDeviceType(idx: Byte?, type: Byte?) {
- dockList.find { it.addr == idx }?.type = type
- }
- /**
- * 读取卡扣状态
- *
- * @param isLock true:读锁具底座 false:读钥匙底座
- * @param type 0:钥匙底座 1:锁具底座1-8 2:锁具底座9、10
- */
- fun readBuckleStatus(isLock: Boolean, slaveIdx: Int?, doneSingle: ((type: Int, res: ByteArray) -> Unit)? = null) {
- // TODO 电磁锁控制板可能不是,并且锁和钥匙的读取不一样
- slaveIdx?.let {
- modBusManager?.sendTo(it, MBFrame.READ_BUCKLE_STATUS) { res ->
- doneSingle?.invoke(if (isLock) 1 else 0, res)
- }
- if (isLock) {
- modBusManager?.sendTo(it, MBFrame.READ_LOCK_BUCKLE_EXTRA_STATUS) { res ->
- doneSingle?.invoke(2, res)
- }
- }
- }
- }
- /**
- * 开/关锁具卡扣
- */
- fun controlLockBuckle(isOpen: Boolean, slaveIdx: Int?, lockIdx: Int, done: ((res: ByteArray) -> Unit)? = null) {
- slaveIdx?.let {
- modBusManager?.generateLockBuckleCmd(isOpen, lockIdx)?.let { cmd ->
- modBusManager?.sendTo(it, cmd) { res ->
- done?.invoke(res)
- }
- }
- }
- }
- fun controlLockBuckle(isOpen: Boolean, slaveIdx: Int?, lockIdxList: MutableList<Int>, done: ((res: ByteArray) -> Unit)? = null) {
- slaveIdx?.let {
- modBusManager?.generateLockBuckleCmd(isOpen, lockIdxList)?.let { cmdList ->
- cmdList.forEach { cmd ->
- modBusManager?.sendTo(it, cmd) { res ->
- done?.invoke(res)
- }
- }
- }
- }
- }
- /**
- * 读取钥匙RFID
- */
- fun readKeyRfid(slaveIdx: Int?, isLeft: Boolean, done: ((isLeft: Boolean, res: ByteArray) -> Unit)? = null) {
- slaveIdx?.let {
- modBusManager?.generateRfidCmd(if (isLeft) 0 else 1)?.let { cmd ->
- modBusManager?.sendTo(it, cmd) {
- done?.invoke(isLeft, it)
- }
- }
- }
- }
- /**
- * 读取锁具RFID
- */
- fun readLockRfid(slaveIdx: Int?, lockIdx: Int, done: ((res: ByteArray) -> Unit)? = null) {
- slaveIdx?.let {
- modBusManager?.generateRfidCmd(lockIdx)?.let { cmd ->
- modBusManager?.sendTo(it, cmd) { res ->
- done?.invoke(res)
- }
- }
- }
- }
- /**
- * 更新钥匙RFID
- */
- fun updateKeyRfid(slaveIdx: Int, isLeft: Boolean, rfid: String) {
- dockList.find { it.addr.toInt() == slaveIdx }?.getKeyList()?.find { it.isLeft == isLeft }?.rfid = rfid
- }
- /**
- * 通过RFID更新对应的Mac
- */
- fun updateKeyMacByRfid(rfid: String, mac: String) {
- dockList.find { it.type == DOCK_TYPE_KEY }?.getKeyList()?.find { it.rfid == rfid }?.mac = mac
- }
- /**
- * 更新锁具RFID
- */
- fun updateLockRfid(slaveIdx: Int, lockIdx: Int, rfid: String) {
- dockList.find { it.addr.toInt() == slaveIdx }?.getLockList()?.find { it.idx == lockIdx }?.rfid = rfid
- }
- /**
- * 操作钥匙灯
- *
- * @param leftAction、rightAction 0:保持当前状态 1:点亮 2:熄灭 默认0
- */
- fun controlKeyLight(slaveIdx: Int?, leftAction: Int = 0, rightAction: Int = 0, done: ((res: ByteArray) -> Unit)? = null) {
- slaveIdx?.let {
- modBusManager?.generateKeyLightCmd(leftAction, rightAction)?.let { cmd ->
- modBusManager?.sendTo(it, cmd) {
- done?.invoke(it)
- }
- }
- }
- }
- /**
- * 开/关钥匙卡扣
- *
- * @param isOpen true:开操作 false:关操作
- * @param isLeft true:左卡扣 false:右卡扣
- */
- fun controlKeyBuckle(isOpen: Boolean, isLeft: Boolean, slaveIdx: Int?, done: ((res: ByteArray) -> Unit)? = null) {
- slaveIdx?.let {
- modBusManager?.generateKeyBuckleCmd(isOpen, if (isLeft) 0 else 1)?.let { cmd ->
- modBusManager?.sendTo(it, cmd) { res ->
- done?.invoke(res)
- }
- }
- }
- }
- /**
- * 根据RFID找钥匙
- */
- fun getKeyByRfid(rfid: String): DockBean.KeyBean? {
- return dockList.find { it.type == DOCK_TYPE_KEY }?.getKeyList()?.find { it.rfid == rfid }
- }
- /**
- * 根据RFID找锁具
- */
- fun getLockByRfid(rfid: String): DockBean.LockBean? {
- return dockList.find { it.type == DOCK_TYPE_LOCK }?.getLockList()?.find { it.rfid == rfid }
- }
- }
|