ModBusController.kt 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. package com.grkj.iscs.modbus
  2. import android.content.Context
  3. import com.grkj.iscs.util.Executor
  4. import com.grkj.iscs.util.log.LogUtil
  5. import java.util.concurrent.Executors
  6. /**
  7. * ModBus 主控板控制器
  8. */
  9. object ModBusController {
  10. /**
  11. * 所有的设备列表
  12. */
  13. var deviceList: MutableList<DeviceBean> = mutableListOf()
  14. private const val LISTENER_TYPE_STATUS = 3
  15. // 主控板管理器
  16. private var modBusManager: ModBusManager? = null
  17. private var slaveCount: Int = 0
  18. private val threadPool = Executors.newScheduledThreadPool(4)
  19. private val listeners = ArrayList<StatusListener>()
  20. // 是否中断读取状态
  21. private var interruptReadStatus: ArrayList<Boolean> = ArrayList()
  22. var shouldStopUpgrade = false
  23. fun setSlaveCount(count: Int) {
  24. modBusManager?.slaveCount = count
  25. slaveCount = count
  26. }
  27. class StatusListener(
  28. val key: Any,
  29. val listener: (Any) -> Unit,
  30. val type: Int
  31. )
  32. fun interruptReadTrashBinStatus(interrupt: Boolean) {
  33. interruptReadStatus.clear()
  34. interruptReadStatus.add(interrupt)
  35. }
  36. @ExperimentalUnsignedTypes
  37. fun start(ctx: Context) {
  38. modBusManager?.stop()
  39. PortManager.openCtrlBord(ctx)
  40. ?.let { pm ->
  41. return@let ModBusManager(slaveCount, pm, true)
  42. }
  43. // 间隔 1 秒读一遍桶的状态
  44. ?.repeatSendToAll(MBFrame.READ_STATUS, {
  45. interruptReadStatus
  46. }, { res ->
  47. // // Logger.d("ModbusController", "res: ${res.map { it.toHexString() }}")
  48. LogUtil.i("****************************************************************************")
  49. for (l in listeners) {
  50. if (l.type == LISTENER_TYPE_STATUS) {
  51. l.listener(res)
  52. }
  53. }
  54. // TODO 临时改成5s
  55. // }, 1000)
  56. }, 5000)
  57. ?.also {
  58. modBusManager = it
  59. Executor.runOnIO {
  60. // refreshAllowOpenDoorUnidentified(ctx, it)
  61. }
  62. }
  63. ?.start()
  64. }
  65. fun registerStatusListener(key: Any, listener: (Any) -> Unit) {
  66. listeners.add(StatusListener(key, listener, LISTENER_TYPE_STATUS))
  67. }
  68. fun unregisterListener(key: Any) {
  69. val it = listeners.iterator()
  70. while (it.hasNext()) {
  71. if (it.next().key == key) {
  72. it.remove()
  73. }
  74. }
  75. }
  76. fun stop() {
  77. modBusManager?.stop()
  78. }
  79. /*****************************************************************************************/
  80. /**
  81. * 初始化所有设备的状态
  82. */
  83. // TODO 通电后多久执行?App每次重启的执行是什么
  84. fun initDevicesStatus() {
  85. readDeviceType { res ->
  86. res.forEach { bytes ->
  87. if (bytes.size < 5) return@forEach
  88. // TODO 设备具体数据由0x0011寄存器提供
  89. updateDeviceType(bytes[0], bytes[4])
  90. val type = when (bytes[4]) {
  91. 0x00.toByte() -> "钥匙底座"
  92. 0x01.toByte() -> "锁具底座"
  93. 0x02.toByte() -> "电磁锁控制板"
  94. else -> "未知"
  95. }
  96. LogUtil.i("initDevicesStatus 设备(${bytes[0].toInt()})类型:$type")
  97. }
  98. }
  99. Executor.delayOnIO({
  100. // TODO 待完善
  101. initLock() // TODO 打开所有无锁的卡扣、读取所有锁的RFID
  102. initKey() // TODO 打开所有无钥匙的卡扣、关闭所有钥匙灯光、读取所有钥匙的RFID
  103. // TODO 设置所有钥匙的模式
  104. // TODO 通过HTTP获取所有钥匙的Mac
  105. }, 3000)
  106. }
  107. /**
  108. * 初始化锁具——打开所有无锁的卡扣、读取RFID
  109. */
  110. private fun initLock() {
  111. LogUtil.i("initLock : $deviceList")
  112. deviceList.filter { it.type == 0x01.toByte() }.forEach { deviceBean ->
  113. deviceBean.lockList.forEach { lockBean ->
  114. if (lockBean.hasLock) {
  115. LogUtil.i("initLock rfid: ${deviceBean.idx!!.toInt() - 1} : ${lockBean.idx}")
  116. readLockRfid(deviceBean.idx!!.toInt() - 1, lockBean.idx)
  117. } else {
  118. LogUtil.i("initLock buckle : ${deviceBean.idx!!.toInt() - 1} : ${lockBean.idx}")
  119. controlLockBuckle(false, deviceBean.idx!!.toInt() - 1, lockBean.idx)
  120. }
  121. }
  122. }
  123. }
  124. /**
  125. * 初始化钥匙——关闭所有钥匙灯光
  126. */
  127. private fun initKey() {
  128. LogUtil.i("initKey : $deviceList")
  129. deviceList.filter { it.type == 0x00.toByte() }.forEach { deviceBean ->
  130. controlKeyLight(deviceBean.idx!!.toInt() - 1, 2, 2)
  131. deviceBean.keyList.forEach { key ->
  132. if (key.hasKey) {
  133. LogUtil.i("initKey : ${deviceBean.idx!!.toInt() - 1} : ${key.isLeft}")
  134. readKeyRfid(deviceBean.idx!!.toInt() - 1, key.isLeft)
  135. } else {
  136. // TODO 关闭钥匙卡扣
  137. }
  138. }
  139. }
  140. }
  141. /**
  142. * 更新状态
  143. */
  144. fun updateStatus(byteArray: ByteArray): Any? {
  145. if (byteArray.isEmpty()) {
  146. return null
  147. }
  148. val deviceBean = deviceList.find { it.idx == byteArray[0] }
  149. return deviceBean?.parseStatus(byteArray) ?: let {
  150. val temp = DeviceBean(byteArray[0], null, mutableListOf(), mutableListOf())
  151. deviceList.add(temp)
  152. temp.parseStatus(byteArray)
  153. }
  154. }
  155. /**
  156. * 读取设备类型
  157. */
  158. fun readDeviceType(done: ((res: List<ByteArray>) -> Unit)? = null) {
  159. modBusManager?.sendToAll(MBFrame.READ_DEVICE_TYPE) { res ->
  160. done?.invoke(res)
  161. }
  162. }
  163. /**
  164. * 更新设备类型
  165. */
  166. fun updateDeviceType(idx: Byte?, type: Byte?) {
  167. deviceList.find { it.idx == idx }?.type = type
  168. }
  169. /**
  170. * 读取卡扣状态
  171. *
  172. * @param isLock true:读锁具底座 false:读钥匙底座
  173. * @param type 0:钥匙底座 1:锁具底座1-8 2:锁具底座9、10
  174. */
  175. fun readBuckleStatus(isLock: Boolean, slaveIdx: Int?, doneSingle: ((type: Int, res: ByteArray) -> Unit)? = null) {
  176. // TODO 电磁锁控制板可能不是,并且锁和钥匙的读取不一样
  177. slaveIdx?.let {
  178. modBusManager?.sendTo(it, MBFrame.READ_BUCKLE_STATUS) { res ->
  179. doneSingle?.invoke(if (isLock) 1 else 0, res)
  180. }
  181. if (isLock) {
  182. modBusManager?.sendTo(it, MBFrame.READ_LOCK_BUCKLE_EXTRA_STATUS) { res ->
  183. doneSingle?.invoke(2, res)
  184. }
  185. }
  186. }
  187. }
  188. /**
  189. * 开/关锁具卡扣
  190. */
  191. fun controlLockBuckle(isOpen: Boolean, slaveIdx: Int?, lockIdx: Int, done: ((res: ByteArray) -> Unit)? = null) {
  192. slaveIdx?.let {
  193. modBusManager?.generateLockBuckleCmd(isOpen, lockIdx)?.let { cmd ->
  194. modBusManager?.sendTo(it, cmd) { res ->
  195. done?.invoke(res)
  196. }
  197. }
  198. }
  199. }
  200. /**
  201. * 读取钥匙RFID
  202. */
  203. fun readKeyRfid(slaveIdx: Int?, isLeft: Boolean, done: ((isLeft: Boolean, res: ByteArray) -> Unit)? = null) {
  204. slaveIdx?.let {
  205. modBusManager?.generateKeyRfidCmd(isLeft)?.let { cmd ->
  206. modBusManager?.sendTo(it, cmd) {
  207. done?.invoke(isLeft, it)
  208. }
  209. }
  210. }
  211. }
  212. /**
  213. * 读取锁具RFID
  214. */
  215. fun readLockRfid(slaveIdx: Int?, lockIdx: Int, done: ((res: ByteArray) -> Unit)? = null) {
  216. slaveIdx?.let {
  217. modBusManager?.generateLockRfidCmd(lockIdx)?.let { cmd ->
  218. modBusManager?.sendTo(it, cmd) { res ->
  219. done?.invoke(res)
  220. }
  221. }
  222. }
  223. }
  224. /**
  225. * 更新钥匙RFID
  226. */
  227. fun updateKeyRfid(slaveIdx: Int, isLeft: Boolean, rfid: String) {
  228. deviceList.find { it.idx?.toInt() == slaveIdx }?.keyList?.find { it.isLeft == isLeft }?.rfid = rfid
  229. }
  230. /**
  231. * 通过RFID更新对应的Mac
  232. */
  233. fun updateKeyMacByRfid(rfid: String, mac: String) {
  234. deviceList.find { it.type == 0x00.toByte() }?.keyList?.find { it.rfid == rfid }?.mac = mac
  235. }
  236. /**
  237. * 更新锁具RFID
  238. */
  239. fun updateLockRfid(slaveIdx: Int, lockIdx: Int, rfid: String) {
  240. deviceList.find { it.idx?.toInt() == slaveIdx }?.lockList?.find { it.idx == lockIdx }?.rfid = rfid
  241. }
  242. /**
  243. * 操作钥匙灯
  244. *
  245. * @param leftAction、rightAction 0:保持当前状态 1:点亮 2:熄灭 默认0
  246. */
  247. fun controlKeyLight(slaveIdx: Int?, leftAction: Int = 0, rightAction: Int = 0, done: ((res: ByteArray) -> Unit)? = null) {
  248. slaveIdx?.let {
  249. modBusManager?.generateKeyLightCmd(leftAction, rightAction)?.let { cmd ->
  250. modBusManager?.sendTo(it, cmd) {
  251. done?.invoke(it)
  252. }
  253. }
  254. }
  255. }
  256. /**
  257. * 开/关钥匙卡扣
  258. *
  259. * @param isOpen true:开操作 false:关操作
  260. * @param isLeft true:左卡扣 false:右卡扣
  261. */
  262. fun controlKeyBuckle(isOpen: Boolean, isLeft: Boolean, slaveIdx: Int?, done: ((res: ByteArray) -> Unit)? = null) {
  263. slaveIdx?.let {
  264. modBusManager?.generateKeyBuckleCmd(isOpen, isLeft)?.let { cmd ->
  265. modBusManager?.sendTo(it, cmd) { res ->
  266. done?.invoke(res)
  267. }
  268. }
  269. }
  270. }
  271. /**
  272. * 根据RFID找钥匙
  273. */
  274. fun getKeyByRfid(rfid: String): DeviceBean.KeyBean? {
  275. return deviceList.find { it.type == 0x00.toByte() }?.keyList?.find { it.rfid == rfid }
  276. }
  277. /**
  278. * 根据RFID找锁具
  279. */
  280. fun getLockByRfid(rfid: String): DeviceBean.LockBean? {
  281. return deviceList.find { it.type == 0x01.toByte() }?.lockList?.find { it.rfid == rfid }
  282. }
  283. }