| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281 |
- const {
- toFiniteNumber
- } = require('../utils/number-format.js')
- const {
- clampInteger
- } = require('../utils/base-utils.js')
- const {
- getWxApi
- } = require('../utils/platform-utils.js')
- const STORAGE_KEY = 'app-settings'
- const PROTOCOL_MODE = {
- MODBUS_RTU: 'modbus-rtu',
- STORAGE_ACCESS: 'storage-access'
- }
- const LEGACY_PROTOCOL_MODE_ALIASES = {
- generic: PROTOCOL_MODE.MODBUS_RTU,
- private: PROTOCOL_MODE.STORAGE_ACCESS
- }
- const PROTOCOL_OPTIONS = [
- { key: PROTOCOL_MODE.STORAGE_ACCESS, label: '存储访问' },
- { key: PROTOCOL_MODE.MODBUS_RTU, label: '标准Modbus' }
- ]
- const DEFAULT_SETTINGS = {
- modbusSlaveAddress: 'F0',
- nightModeEnabled: false,
- nightModeFollowSystem: true,
- parameterAutoPollEnabled: false,
- parameterMaxPacketLength: 64,
- parameterPollInterval: 100,
- protocolMode: PROTOCOL_MODE.STORAGE_ACCESS
- }
- 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 normalizeHexByte(value, fallback = DEFAULT_SETTINGS.modbusSlaveAddress) {
- const fallbackText = String(fallback || DEFAULT_SETTINGS.modbusSlaveAddress).toUpperCase()
- const text = String(value === undefined || value === null ? '' : value).trim()
- const hexText = text.toUpperCase().startsWith('0X') ? text.slice(2) : text
- if (!/^[0-9A-F]{1,2}$/i.test(hexText)) return fallbackText
- return parseInt(hexText, 16).toString(16).toUpperCase().padStart(2, '0')
- }
- 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 normalizeProtocolMode(value) {
- const key = String(value || '').trim()
- const normalizedKey = LEGACY_PROTOCOL_MODE_ALIASES[key] || key
- const matched = PROTOCOL_OPTIONS.find((option) => option.key === key)
- if (matched) return matched.key
- const normalizedMatched = PROTOCOL_OPTIONS.find((option) => option.key === normalizedKey)
- return normalizedMatched ? normalizedMatched.key : DEFAULT_SETTINGS.protocolMode
- }
- function isModbusProtocol(value = state.protocolMode) {
- return normalizeProtocolMode(value) === PROTOCOL_MODE.MODBUS_RTU
- }
- function isStorageAccessProtocol(value = state.protocolMode) {
- return normalizeProtocolMode(value) === PROTOCOL_MODE.STORAGE_ACCESS
- }
- function parseHexByte(value, label = '从机地址') {
- const text = String(value === undefined || value === null ? '' : value).trim()
- const hexText = text.toUpperCase().startsWith('0X') ? text.slice(2) : text
- if (!/^[0-9A-F]{1,2}$/i.test(hexText)) {
- throw new Error(`${label}需为 00 - FF`)
- }
- return parseInt(hexText, 16)
- }
- function migrateLegacySettings(settings = {}) {
- const hasProtocolMode = settings.protocolMode !== undefined && settings.protocolMode !== null && settings.protocolMode !== ''
- const hasParameterAutoPollEnabled = settings.parameterAutoPollEnabled !== undefined
- const hasParameterMaxPacketLength = settings.parameterMaxPacketLength !== undefined
- const hasParameterPollInterval = settings.parameterPollInterval !== undefined
- return {
- ...settings,
- protocolMode: hasProtocolMode ? settings.protocolMode : settings.modbusProtocolMode,
- parameterAutoPollEnabled: hasParameterAutoPollEnabled
- ? settings.parameterAutoPollEnabled
- : settings.genericModbusAutoPollEnabled,
- parameterMaxPacketLength: hasParameterMaxPacketLength
- ? settings.parameterMaxPacketLength
- : settings.genericModbusMaxPacketLength,
- parameterPollInterval: hasParameterPollInterval
- ? settings.parameterPollInterval
- : settings.genericModbusPollInterval
- }
- }
- function normalizeSettings(settings = {}) {
- const migratedSettings = migrateLegacySettings(settings)
- const protocolMode = normalizeProtocolMode(migratedSettings.protocolMode)
- const parameterAutoPollEnabled = !!migratedSettings.parameterAutoPollEnabled
- const parameterMaxPacketLength = normalizeParameterPacketLength(
- migratedSettings.parameterMaxPacketLength,
- DEFAULT_SETTINGS.parameterMaxPacketLength
- )
- const parameterPollInterval = clampInteger(
- migratedSettings.parameterPollInterval,
- STATUS_POLL_MIN_INTERVAL,
- STATUS_POLL_MAX_INTERVAL,
- DEFAULT_SETTINGS.parameterPollInterval
- )
- return {
- modbusSlaveAddress: normalizeHexByte(migratedSettings.modbusSlaveAddress),
- nightModeEnabled: !!migratedSettings.nightModeEnabled,
- nightModeFollowSystem: migratedSettings.nightModeFollowSystem !== false,
- parameterAutoPollEnabled,
- 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 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,
- isModbusProtocol,
- isStorageAccessProtocol,
- setModbusSlaveAddress,
- setNightModeEnabled,
- setNightModeFollowSystem,
- setParameterAutoPollEnabled,
- setParameterMaxPacketLength,
- setParameterPollInterval,
- setProtocolMode,
- subscribe
- }
|