const parameterGroupService = require('./service.js') const { validateValueFormula } = require('../../domain/parameter-groups/value-formula.js') const settingsService = require('../../store/settings-store.js') const themeService = require('../../store/theme-store.js') const transport = require('../../transport/ble-core.js') function getOption(options, index) { return options[Number(index)] || options[0] || {} } function getPageState() { const settingsState = settingsService.getState() const transportState = transport.getState() const isModbusProtocol = settingsService.isModbusProtocol(settingsState.protocolMode) const isStorageAccessProtocol = settingsService.isStorageAccessProtocol(settingsState.protocolMode) return { ...parameterGroupService.getState(), ...themeService.getState(), ...settingsState, connectedDevice: transportState.connectedDevice, isModbusProtocol, isStorageAccessProtocol } } function resolveActiveParamView(currentView) { return currentView === 'parameterGroup' ? currentView : 'parameterGroups' } function getSettingsPageState(currentData, settingsState) { const isModbusProtocol = settingsService.isModbusProtocol(settingsState.protocolMode) const isStorageAccessProtocol = settingsService.isStorageAccessProtocol(settingsState.protocolMode) return { ...settingsState, activeParamView: resolveActiveParamView(currentData.activeParamView), isModbusProtocol, isStorageAccessProtocol } } function getVisiblePageState(currentData) { const settingsState = settingsService.getState() const transportState = transport.getState() const isModbusProtocol = settingsService.isModbusProtocol(settingsState.protocolMode) const isStorageAccessProtocol = settingsService.isStorageAccessProtocol(settingsState.protocolMode) const pageState = { ...parameterGroupService.getState(), ...themeService.getState(), ...settingsState, connectedDevice: transportState.connectedDevice, isModbusProtocol, isStorageAccessProtocol } return { ...pageState, activeParamView: resolveActiveParamView(currentData.activeParamView) } } function getTransportPageState(transportState = transport.getState()) { return { connectedDevice: transportState.connectedDevice } } function createParameterDialogState(overrides = {}) { const registerType = getOption(parameterGroupService.REGISTER_TYPE_OPTIONS, 0) const dataType = getOption(parameterGroupService.DATA_TYPE_OPTIONS, 0) return { cancelText: '取消', confirmText: '确认', dataTypeIndex: 0, dataTypeText: dataType.label || '', groupId: '', groupName: '', mode: '', name: '', quantity: '1', registerIndex: -1, registerTypeIndex: 0, registerTypeText: registerType.label || '', remark: '', startAddress: '0000', title: '', textByteLength: '32', showTextLength: false, unit: '', visible: false, maxValue: '', minValue: '', conversionFormula: '', conversionFormulaErrorText: '', addressText: '', displayValue: '', rawValueText: '', showDataType: false, showRange: false, showUnit: false, readOnly: false, parsedStructRegisters: [], structDefinition: '', structParsedSummary: '', ...overrides } } function createParameterGroupDialogState(group) { const isEdit = !!group const registerTypeIndex = isEdit ? (group.registerTypeIndex || 0) : 0 const registerType = getOption(parameterGroupService.REGISTER_TYPE_OPTIONS, registerTypeIndex) return createParameterDialogState({ confirmText: isEdit ? '保存' : '确认', groupId: isEdit ? group.id : '', groupName: isEdit ? group.name : '寄存器组', layout: isEdit ? (group.layout || 'register') : 'register', mode: isEdit ? 'editGroup' : 'createGroup', quantity: isEdit ? String(group.quantity || 1) : '1', registerTypeIndex, registerTypeText: registerType.label || '', startAddress: isEdit && group.startAddressText ? group.startAddressText.replace(/^0x/i, '') : '0000', title: isEdit ? '编辑寄存器组' : '添加寄存器组', visible: true }) } function createParameterRegisterDialogState(mode, group, register, registerIndex) { const isView = mode === 'viewRegister' const dataTypeIndex = register.dataTypeIndex || 0 const dataType = getOption(parameterGroupService.DATA_TYPE_OPTIONS, dataTypeIndex) return createParameterDialogState({ cancelText: isView ? '关闭' : '取消', confirmText: isView ? '' : '保存', dataTypeIndex, dataTypeText: register.dataTypeText || dataType.label || '', groupId: group.id, groupName: group.name, mode, name: register.name, registerIndex, registerTypeIndex: group.registerTypeIndex || 0, remark: register.remark || '', startAddress: group.startAddressText ? group.startAddressText.replace(/^0x/i, '') : '0000', title: isView ? '寄存器信息' : '寄存器配置', textByteLength: String(register.textByteLength || '32'), showTextLength: !!register.showTextLength, unit: register.unit || '', visible: true, conversionFormula: register.conversionFormula || '', conversionFormulaErrorText: register.conversionFormulaErrorText || '', maxValue: register.maxValue || '', minValue: register.minValue || '', addressText: register.addressRangeText || register.addressText || '', displayValue: register.displayValue || '', rawValueText: register.rawValueText || '--', sourceMetaText: register.sourceMetaText || '', showDataType: !!register.showDataType, showRange: !!register.showRange, showUnit: !!register.showUnit, readOnly: isView }) } function getDialogDataTypeState(dialog, dataTypeOptions, dataTypeIndex) { const dataType = getOption(dataTypeOptions, dataTypeIndex) const isTextType = dataType.kind === 'text' const showUnit = dataType.kind === 'number' && dataType.key !== 'hex' return { dataTypeIndex, dataTypeText: dataType.label || '', maxValue: isTextType ? '' : dialog.maxValue, minValue: isTextType ? '' : dialog.minValue, showRange: !isTextType, showTextLength: isTextType, showUnit, textByteLength: isTextType ? (dialog.textByteLength || '32') : dialog.textByteLength, unit: showUnit ? dialog.unit : '' } } function createParameterGroupConfig(dialog) { const registers = Array.isArray(dialog.parsedStructRegisters) ? dialog.parsedStructRegisters : [] return { groupName: dialog.groupName, layout: registers.length ? 'struct' : (dialog.layout || 'register'), quantity: registers.length ? String(registers.length) : dialog.quantity, registerTypeIndex: dialog.registerTypeIndex, startAddress: dialog.startAddress, ...(registers.length ? { registers: registers.map((register) => ({ bitOffset: register.bitOffset, bitWidth: register.bitWidth, byteStart: register.byteStart, dataType: register.dataType, isBitField: !!register.isBitField, isStructField: true, name: register.name, structByteLength: register.structByteLength, textByteLength: register.textByteLength })) } : {}) } } function createParameterRegisterChangedData(dialog, dataTypeOptions) { const dataType = getOption(dataTypeOptions, dialog.dataTypeIndex) const isTextType = dataType.kind === 'text' const showUnit = dataType.kind === 'number' && dataType.key !== 'hex' const conversionFormula = String(dialog.conversionFormula || '').trim() validateValueFormula(conversionFormula) return { name: dialog.name, conversionFormula, dataType: dataType.key, maxValue: isTextType ? '' : dialog.maxValue, minValue: isTextType ? '' : dialog.minValue, remark: dialog.remark, textByteLength: isTextType ? dialog.textByteLength : '', unit: showUnit ? dialog.unit : '' } } function findParameterGroup(groups, groupId) { return (groups || []).find((item) => item.id === groupId) || null } function findParameterRegister(groups, groupId, registerIndex) { const group = findParameterGroup(groups, groupId) const register = group && group.registers ? group.registers[registerIndex] : null return { group, register } } function getActiveParameterGroup(groups, groupId) { return findParameterGroup(groups, groupId) || null } module.exports = { createParameterGroupConfig, createParameterGroupDialogState, createParameterDialogState, createParameterRegisterChangedData, createParameterRegisterDialogState, findParameterGroup, findParameterRegister, getActiveParameterGroup, getDialogDataTypeState, getOption, getPageState, getSettingsPageState, getTransportPageState, getVisiblePageState, resolveActiveParamView }