const storageAccessIo = require('./storage-access-io.js') const { decodeRegisterFromByteCache, decodeRegisterFromWordCache, decodeRegisterValue, formatCoilDisplayValue, formatRegisterValue, normalizeRegister, getRegisterBytesFromByteCache, getRegisterWordsFromByteCache, getRegisterWordsFromWordCache, registerTypeIsBit } = require('../../domain/parameter-groups/model.js') function normalizeNumericCache(source = {}) { const cache = {} Object.keys(source || {}).forEach((addressText) => { const numericAddress = Number(addressText) if (Number.isFinite(numericAddress)) { cache[numericAddress] = Number(source[addressText]) & 0xFFFF } }) return cache } function createRegisterStateFromCache(group, register, wordCache) { const rawBytes = registerTypeIsBit(register) ? [] : (storageAccessIo.isByteAddressedGroup(group) ? getRegisterBytesFromByteCache(register, wordCache) : []) const rawWords = registerTypeIsBit(register) ? [] : (storageAccessIo.isByteAddressedGroup(group) ? getRegisterWordsFromByteCache(register, wordCache) : getRegisterWordsFromWordCache(register, wordCache)) const rawValue = registerTypeIsBit(register) ? decodeRegisterFromWordCache(register, wordCache) : (storageAccessIo.isByteAddressedGroup(group) ? decodeRegisterFromByteCache(register, wordCache) : (rawWords ? decodeRegisterValue(register, rawWords) : null)) const displayValue = rawValue === null || rawValue === undefined ? '--' : (registerTypeIsBit(register) ? formatCoilDisplayValue(rawValue) : formatRegisterValue(register, rawValue)) const preNormalizedRegister = { ...register, displayValue, isDirty: false, rawBytes: rawBytes || [], rawValue, rawWords: rawWords || [] } const nextRegister = normalizeRegister(preNormalizedRegister, group, 0, register.address, register.byteOffset) return { ...nextRegister, id: register.id, inputValue: group.writable ? displayValue : register.inputValue } } function applyReadCacheToGroup(group, wordCache) { return { ...group, registers: group.registers.map((register) => createRegisterStateFromCache(group, register, wordCache)) } } function applyWrittenSnapshotToRegister(register, snapshot = {}) { const hasDisplayValue = Object.prototype.hasOwnProperty.call(snapshot, 'displayValue') const hasRawBytes = Object.prototype.hasOwnProperty.call(snapshot, 'rawBytes') const hasRawValue = Object.prototype.hasOwnProperty.call(snapshot, 'rawValue') const hasRawWords = Object.prototype.hasOwnProperty.call(snapshot, 'rawWords') const nextRegister = { ...register, displayValue: hasDisplayValue ? snapshot.displayValue : register.displayValue, inputValue: hasDisplayValue ? snapshot.displayValue : register.inputValue, isDirty: false, rawBytes: hasRawBytes ? snapshot.rawBytes : register.rawBytes, rawValue: hasRawValue ? snapshot.rawValue : register.rawValue, rawWords: hasRawWords ? snapshot.rawWords : register.rawWords } return nextRegister } function applyWrittenSnapshotsToGroup(group, snapshots = []) { let writtenIndex = 0 return { ...group, registers: group.registers.map((register, index) => { const snapshot = snapshots[writtenIndex] || {} writtenIndex += 1 const nextRegister = applyWrittenSnapshotToRegister(register, snapshot) const normalized = normalizeRegister(nextRegister, group, index, nextRegister.address, nextRegister.byteOffset) return { ...normalized, id: register.id, inputValue: group.writable ? nextRegister.displayValue : nextRegister.inputValue } }) } } function applyWrittenSnapshotToGroupRegister(group, registerIndex, snapshot) { return { ...group, registers: group.registers.map((register, currentIndex) => ( currentIndex === registerIndex ? (() => { const nextRegister = applyWrittenSnapshotToRegister(register, snapshot || {}) const normalized = normalizeRegister(nextRegister, group, currentIndex, nextRegister.address, nextRegister.byteOffset) return { ...normalized, id: register.id, inputValue: group.writable ? nextRegister.displayValue : nextRegister.inputValue } })() : register )) } } module.exports = { applyReadCacheToGroup, applyWrittenSnapshotToGroupRegister, applyWrittenSnapshotsToGroup, normalizeNumericCache }