store.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. const {
  2. migrateLegacyGroupsToProtocol,
  3. persistGroups,
  4. readStoredGroups
  5. } = require('./persistence.js')
  6. const {
  7. getWxApi
  8. } = require('../../utils/platform-utils.js')
  9. const {
  10. normalizeStorageCodeInfoCard,
  11. DATA_TYPE_OPTIONS,
  12. REGISTER_TYPE_OPTIONS,
  13. normalizeGroup
  14. } = require('../../domain/parameter-groups/model.js')
  15. const STORAGE_CODE_INFO_KEY = 'parameter-groups-code-info'
  16. const PROTOCOL_MODE = {
  17. MODBUS_RTU: 'modbus-rtu',
  18. STORAGE_ACCESS: 'storage-access'
  19. }
  20. let initialized = false
  21. const subscribers = []
  22. const DEFAULT_STORAGE_CODE_INFO_CARD = normalizeStorageCodeInfoCard(null)
  23. let state = {
  24. activeProtocolMode: PROTOCOL_MODE.STORAGE_ACCESS,
  25. parameterDataTypeOptions: DATA_TYPE_OPTIONS,
  26. parameterGroupsByProtocol: {
  27. [PROTOCOL_MODE.MODBUS_RTU]: [],
  28. [PROTOCOL_MODE.STORAGE_ACCESS]: []
  29. },
  30. parameterRegisterTypeOptions: REGISTER_TYPE_OPTIONS,
  31. storageCodeInfoCard: DEFAULT_STORAGE_CODE_INFO_CARD
  32. }
  33. function normalizeProtocolMode(protocolMode) {
  34. return protocolMode === PROTOCOL_MODE.MODBUS_RTU
  35. ? PROTOCOL_MODE.MODBUS_RTU
  36. : PROTOCOL_MODE.STORAGE_ACCESS
  37. }
  38. function getActiveProtocolMode() {
  39. return normalizeProtocolMode(state.activeProtocolMode)
  40. }
  41. function getActiveGroups() {
  42. return state.parameterGroupsByProtocol[getActiveProtocolMode()] || []
  43. }
  44. function getGroupsForProtocol(protocolMode = getActiveProtocolMode()) {
  45. return state.parameterGroupsByProtocol[normalizeProtocolMode(protocolMode)] || []
  46. }
  47. function getCodeInfoContext(card = state.storageCodeInfoCard) {
  48. return card && card.codeInfoContext
  49. ? card.codeInfoContext
  50. : {}
  51. }
  52. function normalizeGroupsForProtocol(parameterGroups = [], protocolMode = getActiveProtocolMode(), options = {}) {
  53. const codeInfoContext = protocolMode === PROTOCOL_MODE.STORAGE_ACCESS
  54. ? getCodeInfoContext(options.storageCodeInfoCard)
  55. : {}
  56. return Array.isArray(parameterGroups)
  57. ? parameterGroups.map((group) => normalizeGroup({
  58. ...group,
  59. codeInfoContext
  60. }))
  61. : []
  62. }
  63. function notify() {
  64. const nextState = getState()
  65. subscribers.slice().forEach((subscriber) => {
  66. subscriber(nextState)
  67. })
  68. }
  69. function persistActiveGroups(options = {}) {
  70. if (options.persist === false) return
  71. persistGroups(getActiveGroups(), getActiveProtocolMode())
  72. }
  73. function setState(changedData, options = {}) {
  74. state = {
  75. ...state,
  76. ...changedData
  77. }
  78. persistActiveGroups(options)
  79. notify()
  80. }
  81. function setGroups(parameterGroups, options = {}) {
  82. const protocolMode = normalizeProtocolMode(options.protocolMode || getActiveProtocolMode())
  83. const normalizedGroups = normalizeGroupsForProtocol(parameterGroups, protocolMode)
  84. const parameterGroupsByProtocol = {
  85. ...state.parameterGroupsByProtocol,
  86. [protocolMode]: normalizedGroups
  87. }
  88. state = {
  89. ...state,
  90. parameterGroupsByProtocol
  91. }
  92. if (options.persist !== false) persistGroups(normalizedGroups, protocolMode)
  93. notify()
  94. }
  95. function persistStorageCodeInfoCard(card) {
  96. const wxApi = getWxApi()
  97. if (typeof wxApi.setStorageSync !== 'function') return
  98. try {
  99. wxApi.setStorageSync(STORAGE_CODE_INFO_KEY, JSON.stringify(card || null))
  100. } catch (error) {}
  101. }
  102. function readStorageCodeInfoCard() {
  103. const wxApi = getWxApi()
  104. if (typeof wxApi.getStorageSync !== 'function') return DEFAULT_STORAGE_CODE_INFO_CARD
  105. try {
  106. const jsonText = wxApi.getStorageSync(STORAGE_CODE_INFO_KEY)
  107. return jsonText ? normalizeStorageCodeInfoCard(JSON.parse(jsonText)) : DEFAULT_STORAGE_CODE_INFO_CARD
  108. } catch (error) {
  109. return DEFAULT_STORAGE_CODE_INFO_CARD
  110. }
  111. }
  112. function setStorageCodeInfo(codeInfo, options = {}) {
  113. const card = normalizeStorageCodeInfoCard(codeInfo)
  114. const storageGroups = state.parameterGroupsByProtocol[PROTOCOL_MODE.STORAGE_ACCESS] || []
  115. const normalizedStorageGroups = normalizeGroupsForProtocol(storageGroups, PROTOCOL_MODE.STORAGE_ACCESS, {
  116. storageCodeInfoCard: card
  117. })
  118. state = {
  119. ...state,
  120. parameterGroupsByProtocol: {
  121. ...state.parameterGroupsByProtocol,
  122. [PROTOCOL_MODE.STORAGE_ACCESS]: normalizedStorageGroups
  123. },
  124. storageCodeInfoCard: card
  125. }
  126. if (options.persist !== false) persistGroups(normalizedStorageGroups, PROTOCOL_MODE.STORAGE_ACCESS)
  127. if (options.persist !== false) persistStorageCodeInfoCard(card)
  128. notify()
  129. }
  130. function updateGroups(mapper, options = {}) {
  131. if (typeof mapper !== 'function') return
  132. const protocolMode = normalizeProtocolMode(options.protocolMode || getActiveProtocolMode())
  133. setGroups(getGroupsForProtocol(protocolMode).map((group, index) => mapper(group, index)), {
  134. ...options,
  135. protocolMode
  136. })
  137. }
  138. function switchProtocolMode(protocolMode, options = {}) {
  139. const normalizedProtocolMode = normalizeProtocolMode(protocolMode)
  140. init(normalizedProtocolMode)
  141. if (state.activeProtocolMode === normalizedProtocolMode) {
  142. if (options.notify !== false) notify()
  143. return
  144. }
  145. state = {
  146. ...state,
  147. activeProtocolMode: normalizedProtocolMode
  148. }
  149. if (options.notify !== false) notify()
  150. }
  151. function init(protocolMode = state.activeProtocolMode) {
  152. const normalizedProtocolMode = normalizeProtocolMode(protocolMode)
  153. if (initialized) return
  154. const storageCodeInfoCard = readStorageCodeInfoCard()
  155. migrateLegacyGroupsToProtocol(normalizedProtocolMode)
  156. const protocolOrder = normalizedProtocolMode === PROTOCOL_MODE.MODBUS_RTU
  157. ? [PROTOCOL_MODE.MODBUS_RTU, PROTOCOL_MODE.STORAGE_ACCESS]
  158. : [PROTOCOL_MODE.STORAGE_ACCESS, PROTOCOL_MODE.MODBUS_RTU]
  159. const parameterGroupsByProtocol = {
  160. [PROTOCOL_MODE.MODBUS_RTU]: [],
  161. [PROTOCOL_MODE.STORAGE_ACCESS]: []
  162. }
  163. protocolOrder.forEach((targetProtocolMode) => {
  164. parameterGroupsByProtocol[targetProtocolMode] = normalizeGroupsForProtocol(
  165. readStoredGroups(targetProtocolMode),
  166. targetProtocolMode
  167. )
  168. })
  169. state = {
  170. ...state,
  171. activeProtocolMode: normalizedProtocolMode,
  172. storageCodeInfoCard,
  173. parameterGroupsByProtocol
  174. }
  175. initialized = true
  176. }
  177. function getState() {
  178. return {
  179. activeProtocolMode: getActiveProtocolMode(),
  180. parameterDataTypeOptions: DATA_TYPE_OPTIONS,
  181. parameterGroups: getActiveGroups(),
  182. parameterRegisterTypeOptions: REGISTER_TYPE_OPTIONS,
  183. storageCodeInfoCard: state.storageCodeInfoCard
  184. }
  185. }
  186. function getGroups() {
  187. return getActiveGroups()
  188. }
  189. function findGroup(groupId, protocolMode = getActiveProtocolMode()) {
  190. return getGroupsForProtocol(protocolMode).find((group) => group.id === groupId)
  191. }
  192. function subscribe(subscriber) {
  193. if (typeof subscriber !== 'function') return () => {}
  194. init()
  195. subscribers.push(subscriber)
  196. subscriber(getState())
  197. return () => {
  198. const index = subscribers.indexOf(subscriber)
  199. if (index >= 0) subscribers.splice(index, 1)
  200. }
  201. }
  202. module.exports = {
  203. DATA_TYPE_OPTIONS,
  204. REGISTER_TYPE_OPTIONS,
  205. findGroup,
  206. getGroups,
  207. getState,
  208. init,
  209. setGroups,
  210. setState,
  211. setStorageCodeInfo,
  212. switchProtocolMode,
  213. subscribe,
  214. updateGroups
  215. }