const parameterGroupService = require('./service.js') const POLL_TIMER_ID = '__parameterPoll' 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 === 'parameterGroups' || data.activeParamView === 'parameterGroup') && !!data.connectedDevice && !!data.parameterAutoPollEnabled } function getParameterGroups(data = {}) { return data.parameterGroups || [] } function getPollableGroups(data) { return getParameterGroups(data) .filter((group) => { if (!group || group.addressOverflow) return false if ((group.registers || []).some((register) => register && register.isDirty)) return false if (data.isStorageAccessProtocol) return !!group.sourceMemoryArea return !!group.functionCode }) .sort((left, right) => ( getMemoryAreaOrder(left) - getMemoryAreaOrder(right) || getGroupAddress(left) - getGroupAddress(right) || String(left.name || '').localeCompare(String(right.name || '')) )) } function createParameterGroupPoller(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 } const protocolMode = data.protocolMode for (const group of getPollableGroups(data)) { const latestData = getData() if (!shouldPoll(latestData)) break if (latestData.protocolMode !== protocolMode) break await parameterGroupService.readGroup(group.id, { maxPacketLength: latestData.parameterMaxPacketLength, protocolMode, showModal: false }) } const latestData = getData() if (shouldPoll(latestData)) { schedule(latestData.parameterPollInterval || 100) } }, delay) } function scheduleVisible() { const data = getData() if (!shouldPoll(data)) { clearAll() return } schedule(data.parameterPollInterval || 100) } return { clearAll, clearTimer, schedule, scheduleVisible } } module.exports = { createParameterGroupPoller }