1
0

service.js 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. const transport = require('../../transport/ble-core.js')
  2. const {
  3. DATA_TYPE_OPTIONS,
  4. formatManualMultipleQuantity,
  5. getManualMultipleValueText,
  6. normalizeManualMultipleQuantity,
  7. normalizeManualMultipleValues,
  8. updateManualMultipleTextLength,
  9. updateManualMultipleType,
  10. updateManualMultipleValue,
  11. validateManualMultipleValue
  12. } = require('./multiple-registers.js')
  13. const {
  14. MODBUS_COMMANDS,
  15. buildGeneratedExpectedResponse: buildExpectedResponse,
  16. createProtocolState,
  17. formatGeneratedResponse,
  18. getCommand,
  19. getDefaultCommandValue,
  20. parseHexNumber
  21. } = require('./frame-builder.js')
  22. const state = {
  23. commandIndex: 2,
  24. commandRegisterQuantity: '0001',
  25. commandValue: '0001',
  26. commandValueLabel: '读取数量',
  27. coilEnabled: true,
  28. generatedHex: '',
  29. protocolCommands: MODBUS_COMMANDS,
  30. protocolDataTypeOptions: DATA_TYPE_OPTIONS,
  31. protocolErrorText: '',
  32. protocolMultipleDialog: {
  33. visible: false
  34. },
  35. protocolMultipleExpanded: false,
  36. protocolMultipleValues: [],
  37. protocolResponseText: '',
  38. protocolStatusText: '',
  39. registerAddress: '0000',
  40. showCoilValue: false,
  41. showCommandValue: true,
  42. showRegisterQuantity: false,
  43. slaveAddress: 'F0'
  44. }
  45. const subscribers = []
  46. function setState(changedData) {
  47. Object.assign(state, changedData)
  48. subscribers.slice().forEach((subscriber) => {
  49. subscriber(getState())
  50. })
  51. }
  52. function getState() {
  53. return {
  54. ...state,
  55. protocolCommands: state.protocolCommands.slice(),
  56. protocolDataTypeOptions: state.protocolDataTypeOptions.slice(),
  57. protocolMultipleDialog: {
  58. ...state.protocolMultipleDialog
  59. },
  60. protocolMultipleExpanded: !!state.protocolMultipleExpanded,
  61. protocolMultipleValues: state.protocolMultipleValues.map((item) => ({
  62. ...item
  63. })),
  64. protocolStatusText: state.protocolStatusText || ''
  65. }
  66. }
  67. function subscribe(subscriber) {
  68. if (typeof subscriber !== 'function') return () => {}
  69. subscribers.push(subscriber)
  70. subscriber(getState())
  71. return () => {
  72. const index = subscribers.indexOf(subscriber)
  73. if (index >= 0) subscribers.splice(index, 1)
  74. }
  75. }
  76. function setProtocolInput(changedData) {
  77. const command = getCommand(changedData.commandIndex === undefined ? state.commandIndex : changedData.commandIndex)
  78. let nextMultipleValues = changedData.protocolMultipleValues
  79. let nextCommandValue = changedData.commandValue
  80. if (
  81. command.inputMode === 'multiple'
  82. && Object.prototype.hasOwnProperty.call(changedData, 'registerAddress')
  83. && !Object.prototype.hasOwnProperty.call(changedData, 'protocolMultipleValues')
  84. ) {
  85. try {
  86. const startAddress = parseHexNumber(changedData.registerAddress, '起始地址', 0xFFFF)
  87. nextMultipleValues = normalizeManualMultipleValues(
  88. normalizeManualMultipleQuantity(state.commandRegisterQuantity),
  89. state.protocolMultipleValues,
  90. startAddress
  91. )
  92. nextCommandValue = getManualMultipleValueText(nextMultipleValues)
  93. } catch (error) {}
  94. }
  95. const nextState = {
  96. commandIndex: state.commandIndex,
  97. commandRegisterQuantity: state.commandRegisterQuantity,
  98. slaveAddress: state.slaveAddress,
  99. registerAddress: state.registerAddress,
  100. commandValue: state.commandValue,
  101. coilEnabled: state.coilEnabled,
  102. ...changedData,
  103. ...(nextMultipleValues ? { protocolMultipleValues: nextMultipleValues } : {}),
  104. ...(nextCommandValue !== undefined ? { commandValue: nextCommandValue } : {})
  105. }
  106. setState({
  107. ...changedData,
  108. ...(nextMultipleValues ? { protocolMultipleValues: nextMultipleValues } : {}),
  109. ...(nextCommandValue !== undefined ? { commandValue: nextCommandValue } : {}),
  110. protocolResponseText: '',
  111. protocolStatusText: '',
  112. ...createProtocolState(
  113. nextState.commandIndex,
  114. nextState.slaveAddress,
  115. nextState.registerAddress,
  116. nextState.commandValue,
  117. nextState.coilEnabled,
  118. nextState.commandRegisterQuantity
  119. )
  120. })
  121. }
  122. function setCommandIndex(index) {
  123. const commandIndex = Number(index)
  124. const command = getCommand(commandIndex)
  125. let protocolMultipleValues = state.protocolMultipleValues
  126. let commandValue = getDefaultCommandValue(command)
  127. if (command.inputMode === 'multiple') {
  128. let startAddress = 0
  129. try {
  130. startAddress = parseHexNumber(state.registerAddress, '起始地址', 0xFFFF)
  131. } catch (error) {}
  132. protocolMultipleValues = normalizeManualMultipleValues(
  133. normalizeManualMultipleQuantity(state.commandRegisterQuantity),
  134. state.protocolMultipleValues,
  135. startAddress
  136. )
  137. commandValue = getManualMultipleValueText(protocolMultipleValues)
  138. }
  139. setProtocolInput({
  140. commandIndex,
  141. commandValue,
  142. coilEnabled: true,
  143. commandRegisterQuantity: state.commandRegisterQuantity,
  144. ...(command.inputMode === 'multiple' ? { protocolMultipleValues } : {})
  145. })
  146. }
  147. function openProtocolMultipleDialog() {
  148. let startAddress = 0
  149. try {
  150. startAddress = parseHexNumber(state.registerAddress, '起始地址', 0xFFFF)
  151. } catch (error) {
  152. setState({
  153. protocolErrorText: error.message || '起始地址无效'
  154. })
  155. return
  156. }
  157. const quantity = normalizeManualMultipleQuantity(state.commandRegisterQuantity)
  158. const values = normalizeManualMultipleValues(quantity, state.protocolMultipleValues, startAddress)
  159. setState({
  160. commandRegisterQuantity: formatManualMultipleQuantity(quantity),
  161. protocolMultipleDialog: {
  162. title: '写多个寄存器',
  163. visible: true
  164. },
  165. protocolMultipleExpanded: false,
  166. protocolMultipleValues: values
  167. })
  168. }
  169. function closeProtocolMultipleDialog() {
  170. setState({
  171. protocolMultipleDialog: {
  172. visible: false
  173. }
  174. })
  175. }
  176. function toggleProtocolMultipleExpanded() {
  177. setState({
  178. protocolMultipleExpanded: !state.protocolMultipleExpanded
  179. })
  180. }
  181. function setProtocolMultipleQuantity(value) {
  182. const quantity = normalizeManualMultipleQuantity(value)
  183. let startAddress = 0
  184. try {
  185. startAddress = parseHexNumber(state.registerAddress, '起始地址', 0xFFFF)
  186. } catch (error) {
  187. setState({
  188. commandRegisterQuantity: value,
  189. protocolErrorText: error.message || '起始地址无效'
  190. })
  191. return
  192. }
  193. const values = normalizeManualMultipleValues(quantity, state.protocolMultipleValues, startAddress)
  194. const commandValue = getManualMultipleValueText(values)
  195. setProtocolInput({
  196. commandRegisterQuantity: value,
  197. commandValue,
  198. protocolMultipleValues: values
  199. })
  200. }
  201. function setProtocolMultipleValue(index, value) {
  202. const values = updateManualMultipleValue(state.protocolMultipleValues, index, value)
  203. let startAddress = 0
  204. try {
  205. startAddress = parseHexNumber(state.registerAddress, '起始地址', 0xFFFF)
  206. } catch (error) {
  207. setState({ protocolErrorText: error.message || '起始地址无效' })
  208. return
  209. }
  210. const normalizedValues = normalizeManualMultipleValues(normalizeManualMultipleQuantity(state.commandRegisterQuantity), values, startAddress)
  211. const commandValue = getManualMultipleValueText(normalizedValues)
  212. setProtocolInput({
  213. commandValue,
  214. protocolMultipleValues: normalizedValues
  215. })
  216. }
  217. function setProtocolMultipleType(index, dataTypeIndex) {
  218. const changedValues = updateManualMultipleType(state.protocolMultipleValues, index, dataTypeIndex)
  219. let startAddress = 0
  220. try {
  221. startAddress = parseHexNumber(state.registerAddress, '起始地址', 0xFFFF)
  222. } catch (error) {
  223. setState({ protocolErrorText: error.message || '起始地址无效' })
  224. return
  225. }
  226. const values = normalizeManualMultipleValues(normalizeManualMultipleQuantity(state.commandRegisterQuantity), changedValues, startAddress)
  227. setProtocolInput({
  228. commandValue: getManualMultipleValueText(values),
  229. protocolMultipleValues: values
  230. })
  231. }
  232. function setProtocolMultipleTextLength(index, value) {
  233. const changedValues = updateManualMultipleTextLength(state.protocolMultipleValues, index, value)
  234. let startAddress = 0
  235. try {
  236. startAddress = parseHexNumber(state.registerAddress, '起始地址', 0xFFFF)
  237. } catch (error) {
  238. setState({ protocolErrorText: error.message || '起始地址无效' })
  239. return
  240. }
  241. const values = normalizeManualMultipleValues(normalizeManualMultipleQuantity(state.commandRegisterQuantity), changedValues, startAddress)
  242. setProtocolInput({
  243. commandValue: getManualMultipleValueText(values),
  244. protocolMultipleValues: values
  245. })
  246. }
  247. function validateProtocolMultipleValue(index, value) {
  248. return validateManualMultipleValue(state.protocolMultipleValues, index, value)
  249. }
  250. function buildGeneratedExpectedResponse() {
  251. return buildExpectedResponse(state)
  252. }
  253. async function sendGeneratedFrame() {
  254. if (!state.generatedHex) {
  255. setState({
  256. protocolStatusText: state.protocolErrorText || '请先生成有效帧'
  257. })
  258. return false
  259. }
  260. const expected = buildGeneratedExpectedResponse()
  261. setState({
  262. protocolResponseText: '',
  263. protocolStatusText: ''
  264. })
  265. const response = await transport.enqueueSendFrame(state.generatedHex, 'RTU', expected ? {
  266. expected
  267. } : {})
  268. if (response) {
  269. setState({
  270. protocolResponseText: formatGeneratedResponse(response),
  271. protocolStatusText: ''
  272. })
  273. } else {
  274. setState({
  275. protocolStatusText: '未收到回复'
  276. })
  277. }
  278. return response
  279. }
  280. setState(createProtocolState(
  281. state.commandIndex,
  282. state.slaveAddress,
  283. state.registerAddress,
  284. state.commandValue,
  285. state.coilEnabled,
  286. state.commandRegisterQuantity
  287. ))
  288. module.exports = {
  289. buildGeneratedExpectedResponse,
  290. closeProtocolMultipleDialog,
  291. formatGeneratedResponse,
  292. getState,
  293. openProtocolMultipleDialog,
  294. sendGeneratedFrame,
  295. setCommandIndex,
  296. setProtocolInput,
  297. setProtocolMultipleQuantity,
  298. setProtocolMultipleTextLength,
  299. setProtocolMultipleType,
  300. setProtocolMultipleValue,
  301. subscribe,
  302. toggleProtocolMultipleExpanded,
  303. validateProtocolMultipleValue
  304. }