| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- const genericModbusService = require('./service.js')
- const POLL_TIMER_ID = '__genericPoll'
- const MEMORY_AREA_ORDER = {
- DATA: 0,
- IDATA: 1,
- XDATA: 2,
- CODE: 3,
- BIT: 4
- }
- function getMemoryAreaOrder(group = {}) {
- const key = String(group.sourceMemoryArea || '').trim().toUpperCase()
- return Object.prototype.hasOwnProperty.call(MEMORY_AREA_ORDER, key) ? MEMORY_AREA_ORDER[key] : 99
- }
- function getGroupAddress(group = {}) {
- const sourceAddress = Number(group.sourceAddress)
- if (Number.isFinite(sourceAddress)) return Math.max(0, Math.floor(sourceAddress))
- const startAddress = Number(group.startAddress)
- return Number.isFinite(startAddress) ? Math.max(0, Math.floor(startAddress)) : 0
- }
- function shouldPoll(data) {
- return !!data
- && (data.activeParamView === 'genericModbus' || data.activeParamView === 'genericModbusGroup')
- && !!data.connectedDevice
- && !!data.genericModbusAutoPollEnabled
- }
- function getPollableGroups(data) {
- return (data.genericModbusGroups || [])
- .filter((group) => {
- if (!group || group.addressOverflow) return false
- if ((group.registers || []).some((register) => register && register.isDirty)) return false
- if (data.isPrivateProtocol) return !!group.sourceMemoryArea
- return group.isReadOnly
- })
- .sort((left, right) => (
- getMemoryAreaOrder(left) - getMemoryAreaOrder(right)
- || getGroupAddress(left) - getGroupAddress(right)
- || String(left.name || '').localeCompare(String(right.name || ''))
- ))
- }
- function createGenericModbusPoller(getData) {
- const timers = {}
- function clearTimer(timerId) {
- if (!timers[timerId]) return
- clearTimeout(timers[timerId])
- delete timers[timerId]
- }
- function clearAll() {
- Object.keys(timers).forEach(clearTimer)
- }
- function schedule(delay) {
- clearTimer(POLL_TIMER_ID)
- timers[POLL_TIMER_ID] = setTimeout(async () => {
- const data = getData()
- if (!shouldPoll(data)) {
- clearTimer(POLL_TIMER_ID)
- return
- }
- for (const group of getPollableGroups(data)) {
- const latestData = getData()
- if (!shouldPoll(latestData)) break
- await genericModbusService.readGroup(group.id, {
- maxPacketLength: latestData.genericModbusMaxPacketLength,
- showModal: false
- })
- }
- const latestData = getData()
- if (shouldPoll(latestData)) {
- schedule(latestData.genericModbusPollInterval || 100)
- }
- }, delay)
- }
- function scheduleVisible() {
- const data = getData()
- if (!shouldPoll(data)) {
- clearAll()
- return
- }
- schedule(data.genericModbusPollInterval || 100)
- }
- return {
- clearAll,
- clearTimer,
- schedule,
- scheduleVisible
- }
- }
- module.exports = {
- createGenericModbusPoller
- }
|