1
0

poller.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. const parameterGroupService = require('./service.js')
  2. const {
  3. isParameterGroupPollEnabled
  4. } = require('../../domain/parameter-groups/model.js')
  5. const POLL_TIMER_ID = '__parameterPoll'
  6. const MEMORY_AREA_ORDER = {
  7. ADDR32: 0,
  8. DATA: 1,
  9. IDATA: 2,
  10. XDATA: 3,
  11. CODE: 4,
  12. BIT: 5
  13. }
  14. function getMemoryAreaOrder(group = {}) {
  15. const key = String(group.sourceMemoryArea || '').trim().toUpperCase()
  16. return Object.prototype.hasOwnProperty.call(MEMORY_AREA_ORDER, key) ? MEMORY_AREA_ORDER[key] : 99
  17. }
  18. function getGroupAddress(group = {}) {
  19. const sourceAddress = Number(group.sourceAddress)
  20. if (Number.isFinite(sourceAddress)) return Math.max(0, Math.floor(sourceAddress))
  21. const startAddress = Number(group.startAddress)
  22. return Number.isFinite(startAddress) ? Math.max(0, Math.floor(startAddress)) : 0
  23. }
  24. function shouldPoll(data) {
  25. return !!data
  26. && (data.activeParamView === 'parameterGroups' || data.activeParamView === 'parameterGroup')
  27. && !!data.connectedDevice
  28. && !!data.parameterAutoPollEnabled
  29. }
  30. function getParameterGroups(data = {}) {
  31. return data.parameterGroups || []
  32. }
  33. function getPollableGroups(data) {
  34. return getParameterGroups(data)
  35. .filter((group) => {
  36. if (!group || group.addressOverflow) return false
  37. if (!isParameterGroupPollEnabled(group)) return false
  38. if ((group.registers || []).some((register) => register && register.isDirty)) return false
  39. if (data.isStorageAccessProtocol) {
  40. return !!group.sourceMemoryArea
  41. }
  42. return !!group.functionCode
  43. })
  44. .sort((left, right) => (
  45. getMemoryAreaOrder(left) - getMemoryAreaOrder(right)
  46. || getGroupAddress(left) - getGroupAddress(right)
  47. || String(left.name || '').localeCompare(String(right.name || ''))
  48. ))
  49. }
  50. function createParameterGroupPoller(getData) {
  51. const timers = {}
  52. function clearTimer(timerId) {
  53. if (!timers[timerId]) return
  54. clearTimeout(timers[timerId])
  55. delete timers[timerId]
  56. }
  57. function clearAll() {
  58. Object.keys(timers).forEach(clearTimer)
  59. }
  60. function schedule(delay) {
  61. clearTimer(POLL_TIMER_ID)
  62. timers[POLL_TIMER_ID] = setTimeout(async () => {
  63. const data = getData()
  64. if (!shouldPoll(data)) {
  65. clearTimer(POLL_TIMER_ID)
  66. return
  67. }
  68. const protocolMode = data.protocolMode
  69. for (const group of getPollableGroups(data)) {
  70. const latestData = getData()
  71. if (!shouldPoll(latestData)) break
  72. if (latestData.protocolMode !== protocolMode) break
  73. await parameterGroupService.readGroup(group.id, {
  74. maxPacketLength: latestData.parameterMaxPacketLength,
  75. protocolMode,
  76. showModal: false
  77. })
  78. }
  79. const latestData = getData()
  80. if (shouldPoll(latestData)) {
  81. schedule(latestData.parameterPollInterval || 100)
  82. }
  83. }, delay)
  84. }
  85. function scheduleVisible() {
  86. const data = getData()
  87. if (!shouldPoll(data)) {
  88. clearAll()
  89. return
  90. }
  91. schedule(data.parameterPollInterval || 100)
  92. }
  93. return {
  94. clearAll,
  95. clearTimer,
  96. schedule,
  97. scheduleVisible
  98. }
  99. }
  100. module.exports = {
  101. createParameterGroupPoller
  102. }