store.js 7.1 KB

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