1
0

settings-store.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. const {
  2. clampInteger,
  3. getWxApi,
  4. toFiniteNumber
  5. } = require('../utils/base-utils.js')
  6. const {
  7. normalizeHexByte,
  8. parseHexByte
  9. } = require('../utils/validation.js')
  10. const {
  11. DEFAULT_PROTOCOL_MODE,
  12. PROTOCOL_MODE,
  13. PROTOCOL_OPTIONS,
  14. isModbusProtocolMode,
  15. isNoProtocolMode,
  16. isStorageAccessProtocolMode,
  17. normalizeProtocolMode
  18. } = require('../domain/protocol-mode.js')
  19. const STORAGE_KEY = 'app-settings'
  20. const DEFAULT_SETTINGS = {
  21. modbusSlaveAddress: 'F0',
  22. nightModeEnabled: false,
  23. nightModeFollowSystem: true,
  24. parameterAutoPollEnabled: false,
  25. parameterCardControlEnabled: true,
  26. parameterMaxPacketLength: 64,
  27. parameterPollInterval: 100,
  28. protocolMode: DEFAULT_PROTOCOL_MODE,
  29. storageAccessDefaultEndian: 'little'
  30. }
  31. const STATUS_POLL_MIN_INTERVAL = 100
  32. const STATUS_POLL_MAX_INTERVAL = 3000
  33. const PARAMETER_MIN_PACKET_LENGTH = 14
  34. const state = {
  35. ...DEFAULT_SETTINGS
  36. }
  37. let initialized = false
  38. const subscribers = []
  39. function normalizeParameterPacketLength(value, fallback = DEFAULT_SETTINGS.parameterMaxPacketLength) {
  40. const numberValue = toFiniteNumber(value, NaN)
  41. if (!Number.isFinite(numberValue)) return fallback
  42. const rounded = Math.round(numberValue)
  43. if (rounded <= 0) return 0
  44. return Math.max(rounded, PARAMETER_MIN_PACKET_LENGTH)
  45. }
  46. function normalizeStorageAccessEndian(value, fallback = DEFAULT_SETTINGS.storageAccessDefaultEndian) {
  47. const text = String(value || '').trim().toLowerCase()
  48. if (text === 'big' || text === 'be' || text === '1') return 'big'
  49. if (text === 'little' || text === 'le' || text === '0') return 'little'
  50. return fallback
  51. }
  52. function isModbusProtocol(value = state.protocolMode) {
  53. return isModbusProtocolMode(value)
  54. }
  55. function isStorageAccessProtocol(value = state.protocolMode) {
  56. return isStorageAccessProtocolMode(value)
  57. }
  58. function isNoProtocol(value = state.protocolMode) {
  59. return isNoProtocolMode(value)
  60. }
  61. function normalizeSettings(settings = {}) {
  62. const protocolMode = normalizeProtocolMode(settings.protocolMode)
  63. const parameterAutoPollEnabled = !!settings.parameterAutoPollEnabled
  64. const parameterMaxPacketLength = normalizeParameterPacketLength(
  65. settings.parameterMaxPacketLength,
  66. DEFAULT_SETTINGS.parameterMaxPacketLength
  67. )
  68. const parameterPollInterval = clampInteger(
  69. settings.parameterPollInterval,
  70. STATUS_POLL_MIN_INTERVAL,
  71. STATUS_POLL_MAX_INTERVAL,
  72. DEFAULT_SETTINGS.parameterPollInterval
  73. )
  74. return {
  75. modbusSlaveAddress: normalizeHexByte(settings.modbusSlaveAddress),
  76. nightModeEnabled: !!settings.nightModeEnabled,
  77. nightModeFollowSystem: settings.nightModeFollowSystem !== false,
  78. parameterAutoPollEnabled,
  79. parameterCardControlEnabled: settings.parameterCardControlEnabled !== false,
  80. parameterMaxPacketLength,
  81. parameterPollInterval,
  82. protocolMode,
  83. storageAccessDefaultEndian: normalizeStorageAccessEndian(settings.storageAccessDefaultEndian)
  84. }
  85. }
  86. function readStoredSettings() {
  87. const wxApi = getWxApi()
  88. if (typeof wxApi.getStorageSync !== 'function') return {}
  89. try {
  90. return wxApi.getStorageSync(STORAGE_KEY) || {}
  91. } catch (error) {
  92. return {}
  93. }
  94. }
  95. function persistSettings() {
  96. const wxApi = getWxApi()
  97. if (typeof wxApi.setStorageSync !== 'function') return
  98. try {
  99. wxApi.setStorageSync(STORAGE_KEY, getState())
  100. } catch (error) {}
  101. }
  102. function notify() {
  103. const nextState = getState()
  104. subscribers.slice().forEach((subscriber) => {
  105. subscriber(nextState)
  106. })
  107. }
  108. function setState(changedData, options = {}) {
  109. Object.assign(state, normalizeSettings({
  110. ...state,
  111. ...changedData
  112. }))
  113. if (options.persist !== false) {
  114. persistSettings()
  115. }
  116. notify()
  117. }
  118. function init() {
  119. if (initialized) return
  120. Object.assign(state, normalizeSettings(readStoredSettings()))
  121. initialized = true
  122. }
  123. function getState() {
  124. return {
  125. ...state
  126. }
  127. }
  128. function subscribe(subscriber) {
  129. if (typeof subscriber !== 'function') return () => {}
  130. init()
  131. subscribers.push(subscriber)
  132. subscriber(getState())
  133. return () => {
  134. const index = subscribers.indexOf(subscriber)
  135. if (index >= 0) subscribers.splice(index, 1)
  136. }
  137. }
  138. function setNightModeEnabled(value) {
  139. init()
  140. setState({
  141. nightModeEnabled: !!value
  142. })
  143. }
  144. function setNightModeFollowSystem(value) {
  145. init()
  146. setState({
  147. nightModeFollowSystem: !!value
  148. })
  149. }
  150. function setModbusSlaveAddress(value) {
  151. init()
  152. setState({
  153. modbusSlaveAddress: normalizeHexByte(value, state.modbusSlaveAddress)
  154. })
  155. }
  156. function setProtocolMode(value) {
  157. init()
  158. setState({
  159. protocolMode: normalizeProtocolMode(value)
  160. })
  161. }
  162. function getModbusSlaveAddress() {
  163. init()
  164. return parseHexByte(state.modbusSlaveAddress, 'Modbus从机地址')
  165. }
  166. function setParameterAutoPollEnabled(value) {
  167. init()
  168. setState({
  169. parameterAutoPollEnabled: !!value
  170. })
  171. }
  172. function setParameterCardControlEnabled(value) {
  173. init()
  174. setState({
  175. parameterCardControlEnabled: !!value
  176. })
  177. }
  178. function setParameterMaxPacketLength(value) {
  179. init()
  180. setState({
  181. parameterMaxPacketLength: normalizeParameterPacketLength(value, state.parameterMaxPacketLength)
  182. })
  183. }
  184. function setParameterPollInterval(value) {
  185. init()
  186. setState({
  187. parameterPollInterval: value
  188. })
  189. }
  190. function setStorageAccessDefaultEndian(value) {
  191. init()
  192. setState({
  193. storageAccessDefaultEndian: normalizeStorageAccessEndian(value, state.storageAccessDefaultEndian)
  194. })
  195. }
  196. module.exports = {
  197. PARAMETER_MIN_PACKET_LENGTH,
  198. PROTOCOL_MODE,
  199. PROTOCOL_OPTIONS,
  200. STATUS_POLL_MAX_INTERVAL,
  201. STATUS_POLL_MIN_INTERVAL,
  202. getModbusSlaveAddress,
  203. getState,
  204. init,
  205. isNoProtocol,
  206. isModbusProtocol,
  207. isStorageAccessProtocol,
  208. setModbusSlaveAddress,
  209. setNightModeEnabled,
  210. setNightModeFollowSystem,
  211. setParameterAutoPollEnabled,
  212. setParameterCardControlEnabled,
  213. setParameterMaxPacketLength,
  214. setParameterPollInterval,
  215. setStorageAccessDefaultEndian,
  216. setProtocolMode,
  217. normalizeProtocolMode,
  218. normalizeStorageAccessEndian,
  219. subscribe
  220. }