1
0

sync-service.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. const controlService = require('./control-service')
  2. const {
  3. controlState,
  4. paramsState: paramsPageState
  5. } = require('./motor-control-data')
  6. const transport = require('./ble-transport')
  7. const modbusAccess = require('./modbus-access')
  8. const {
  9. notifyPageToast
  10. } = require('./page-toast')
  11. const {
  12. addCoilReadValues,
  13. addWordReadValues
  14. } = require('./register-value-utils')
  15. const readValues = {
  16. coils: {},
  17. words: {}
  18. }
  19. let paramsSnapshot = paramsPageState.createInitialState()
  20. let paramsSnapshotVersion = 0
  21. const READ_STEPS = [
  22. {
  23. address: 0x00,
  24. functionCode: 0x01,
  25. label: '同步线圈 00-10',
  26. quantity: 17,
  27. onResponse(response, chunk) {
  28. addCoilReadValues(readValues, chunk.address, chunk.quantity, response)
  29. controlService.applyControlReadValues(readValues.coils)
  30. }
  31. },
  32. {
  33. address: 0x30,
  34. functionCode: 0x03,
  35. label: '同步估算器参数 30-4A',
  36. quantity: 27,
  37. onResponse(response, chunk) {
  38. addWordReadValues(readValues, chunk.address, response)
  39. }
  40. },
  41. {
  42. address: 0x60,
  43. functionCode: 0x03,
  44. label: '同步参数配置 60-8D',
  45. quantity: 46,
  46. onResponse(response, chunk) {
  47. addWordReadValues(readValues, chunk.address, response)
  48. controlService.applyMotorReadWords(response.words || [], chunk.address)
  49. }
  50. },
  51. {
  52. address: controlState.DRIVER_PARAM_START_ADDRESS,
  53. functionCode: 0x04,
  54. label: '同步驱动器参数 A0-B3',
  55. quantity: controlState.DRIVER_PARAM_WORD_COUNT,
  56. onResponse(response, chunk) {
  57. addWordReadValues(readValues, chunk.address, response)
  58. controlService.applyDriverReadWords(response.words || [])
  59. }
  60. },
  61. {
  62. address: controlState.STATUS_START_ADDRESS,
  63. functionCode: 0x04,
  64. label: '同步状态',
  65. quantity: () => controlState.getStatusWordCount(controlService.getState().userStatusCount),
  66. onResponse(response, chunk) {
  67. addWordReadValues(readValues, chunk.address, response)
  68. controlService.applyStatusReadWords(response.words || [], chunk.address)
  69. }
  70. }
  71. ]
  72. let syncing = false
  73. const subscribers = []
  74. function getState() {
  75. return {
  76. isSyncing: syncing,
  77. syncVersion: paramsSnapshotVersion
  78. }
  79. }
  80. function notify() {
  81. const state = getState()
  82. subscribers.slice().forEach((subscriber) => {
  83. subscriber(state)
  84. })
  85. }
  86. function setSyncing(value) {
  87. syncing = !!value
  88. notify()
  89. }
  90. transport.subscribe((transportState) => {
  91. if (!transportState.connectedDevice && syncing) {
  92. setSyncing(false)
  93. }
  94. })
  95. function subscribe(subscriber) {
  96. if (typeof subscriber !== 'function') return () => {}
  97. subscribers.push(subscriber)
  98. subscriber(getState())
  99. return () => {
  100. const index = subscribers.indexOf(subscriber)
  101. if (index >= 0) subscribers.splice(index, 1)
  102. }
  103. }
  104. function resetReadValues() {
  105. readValues.coils = {}
  106. readValues.words = {}
  107. }
  108. function getParamsSnapshot() {
  109. return {
  110. ...paramsSnapshot,
  111. syncVersion: paramsSnapshotVersion
  112. }
  113. }
  114. async function syncAllRegisters() {
  115. if (syncing) return false
  116. const transportState = transport.getState()
  117. if (!transportState.connectedDevice) return false
  118. const slaveAddress = modbusAccess.getSharedSlaveAddress()
  119. if (slaveAddress === null) return false
  120. setSyncing(true)
  121. resetReadValues()
  122. try {
  123. for (const step of READ_STEPS) {
  124. const quantity = typeof step.quantity === 'function' ? step.quantity() : step.quantity
  125. const values = await modbusAccess.readSpans(
  126. slaveAddress,
  127. step.functionCode,
  128. [{
  129. address: step.address,
  130. quantity
  131. }],
  132. step.label,
  133. 'sync-read',
  134. {
  135. onChunk(response, chunk) {
  136. if (typeof step.onResponse === 'function') {
  137. step.onResponse(response, chunk)
  138. }
  139. }
  140. }
  141. )
  142. if (!values) return false
  143. if (values.coils) Object.assign(readValues.coils, values.coils)
  144. if (values.words) Object.assign(readValues.words, values.words)
  145. }
  146. paramsSnapshot = paramsPageState.applyReadValues(paramsSnapshot, readValues)
  147. paramsSnapshotVersion += 1
  148. notify()
  149. notifyPageToast('同步完成')
  150. return true
  151. } finally {
  152. setSyncing(false)
  153. }
  154. }
  155. module.exports = {
  156. getParamsSnapshot,
  157. getState,
  158. subscribe,
  159. syncAllRegisters
  160. }