const { clampInteger, getWxApi, toFiniteNumber } = require('../utils/base-utils.js') const { normalizeHexByte, parseHexByte } = require('../utils/validation.js') const { DEFAULT_PROTOCOL_MODE, PROTOCOL_MODE, PROTOCOL_OPTIONS, isModbusProtocolMode, isNoProtocolMode, isStorageAccessProtocolMode, normalizeProtocolMode } = require('../domain/protocol-mode.js') const STORAGE_KEY = 'app-settings' const DEFAULT_SETTINGS = { modbusSlaveAddress: 'F0', nightModeEnabled: false, nightModeFollowSystem: true, parameterAutoPollEnabled: false, parameterCardControlEnabled: true, parameterMaxPacketLength: 64, parameterPollInterval: 100, protocolMode: DEFAULT_PROTOCOL_MODE } const STATUS_POLL_MIN_INTERVAL = 100 const STATUS_POLL_MAX_INTERVAL = 3000 const PARAMETER_MIN_PACKET_LENGTH = 32 const state = { ...DEFAULT_SETTINGS } let initialized = false const subscribers = [] function normalizeParameterPacketLength(value, fallback = DEFAULT_SETTINGS.parameterMaxPacketLength) { const numberValue = toFiniteNumber(value, NaN) if (!Number.isFinite(numberValue)) return fallback const rounded = Math.round(numberValue) if (rounded <= 0) return 0 return Math.max(rounded, PARAMETER_MIN_PACKET_LENGTH) } function isModbusProtocol(value = state.protocolMode) { return isModbusProtocolMode(value) } function isStorageAccessProtocol(value = state.protocolMode) { return isStorageAccessProtocolMode(value) } function isNoProtocol(value = state.protocolMode) { return isNoProtocolMode(value) } function normalizeSettings(settings = {}) { const protocolMode = normalizeProtocolMode(settings.protocolMode) const parameterAutoPollEnabled = !!settings.parameterAutoPollEnabled const parameterMaxPacketLength = normalizeParameterPacketLength( settings.parameterMaxPacketLength, DEFAULT_SETTINGS.parameterMaxPacketLength ) const parameterPollInterval = clampInteger( settings.parameterPollInterval, STATUS_POLL_MIN_INTERVAL, STATUS_POLL_MAX_INTERVAL, DEFAULT_SETTINGS.parameterPollInterval ) return { modbusSlaveAddress: normalizeHexByte(settings.modbusSlaveAddress), nightModeEnabled: !!settings.nightModeEnabled, nightModeFollowSystem: settings.nightModeFollowSystem !== false, parameterAutoPollEnabled, parameterCardControlEnabled: settings.parameterCardControlEnabled !== false, parameterMaxPacketLength, parameterPollInterval, protocolMode } } function readStoredSettings() { const wxApi = getWxApi() if (typeof wxApi.getStorageSync !== 'function') return {} try { return wxApi.getStorageSync(STORAGE_KEY) || {} } catch (error) { return {} } } function persistSettings() { const wxApi = getWxApi() if (typeof wxApi.setStorageSync !== 'function') return try { wxApi.setStorageSync(STORAGE_KEY, getState()) } catch (error) {} } function notify() { const nextState = getState() subscribers.slice().forEach((subscriber) => { subscriber(nextState) }) } function setState(changedData, options = {}) { Object.assign(state, normalizeSettings({ ...state, ...changedData })) if (options.persist !== false) { persistSettings() } notify() } function init() { if (initialized) return Object.assign(state, normalizeSettings(readStoredSettings())) initialized = true } function getState() { return { ...state } } function subscribe(subscriber) { if (typeof subscriber !== 'function') return () => {} init() subscribers.push(subscriber) subscriber(getState()) return () => { const index = subscribers.indexOf(subscriber) if (index >= 0) subscribers.splice(index, 1) } } function setNightModeEnabled(value) { init() setState({ nightModeEnabled: !!value }) } function setNightModeFollowSystem(value) { init() setState({ nightModeFollowSystem: !!value }) } function setModbusSlaveAddress(value) { init() setState({ modbusSlaveAddress: normalizeHexByte(value, state.modbusSlaveAddress) }) } function setProtocolMode(value) { init() setState({ protocolMode: normalizeProtocolMode(value) }) } function getModbusSlaveAddress() { init() return parseHexByte(state.modbusSlaveAddress, 'Modbus从机地址') } function setParameterAutoPollEnabled(value) { init() setState({ parameterAutoPollEnabled: !!value }) } function setParameterCardControlEnabled(value) { init() setState({ parameterCardControlEnabled: !!value }) } function setParameterMaxPacketLength(value) { init() setState({ parameterMaxPacketLength: normalizeParameterPacketLength(value, state.parameterMaxPacketLength) }) } function setParameterPollInterval(value) { init() setState({ parameterPollInterval: value }) } module.exports = { PARAMETER_MIN_PACKET_LENGTH, PROTOCOL_MODE, PROTOCOL_OPTIONS, STATUS_POLL_MAX_INTERVAL, STATUS_POLL_MIN_INTERVAL, getModbusSlaveAddress, getState, init, isNoProtocol, isModbusProtocol, isStorageAccessProtocol, setModbusSlaveAddress, setNightModeEnabled, setNightModeFollowSystem, setParameterAutoPollEnabled, setParameterCardControlEnabled, setParameterMaxPacketLength, setParameterPollInterval, setProtocolMode, normalizeProtocolMode, subscribe }