| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- const {
- buildReadFrame,
- getMaxReadQuantity
- } = require('./modbus-rtu')
- const controlState = require('./control-page-state')
- const controlService = require('./control-service')
- const paramsPageState = require('./params-page-state')
- const transport = require('./ble-transport')
- const {
- notifyPageToast
- } = require('./page-toast')
- const {
- addCoilReadValues,
- addWordReadValues
- } = require('./register-value-utils')
- const readValues = {
- coils: {},
- words: {}
- }
- let paramsSnapshot = paramsPageState.createInitialState()
- let paramsSnapshotVersion = 0
- const READ_STEPS = [
- {
- address: 0x00,
- functionCode: 0x01,
- label: '同步线圈 00-10',
- quantity: 17,
- onResponse(response, step) {
- addCoilReadValues(readValues, step.address, step.quantity, response)
- controlService.applyControlReadValues(readValues.coils)
- }
- },
- {
- address: 0x30,
- functionCode: 0x03,
- label: '同步估算器参数 30-4A',
- quantity: 27,
- onResponse(response, step) {
- addWordReadValues(readValues, step.address, response)
- }
- },
- {
- address: 0x60,
- functionCode: 0x03,
- label: '同步参数配置 60-8D',
- quantity: 46,
- onResponse(response, step) {
- addWordReadValues(readValues, step.address, response)
- controlService.applyMotorReadWords(response.words || [], step.address)
- }
- },
- {
- address: controlState.DRIVER_PARAM_START_ADDRESS,
- functionCode: 0x04,
- label: '同步驱动器硬件参数 A0-B3',
- quantity: controlState.DRIVER_PARAM_WORD_COUNT,
- onResponse(response, step) {
- addWordReadValues(readValues, step.address, response)
- controlService.applyDriverReadWords(response.words || [])
- }
- },
- {
- address: controlState.STATUS_START_ADDRESS,
- functionCode: 0x04,
- label: '同步状态 C0-DC',
- quantity: controlState.STATUS_WORD_COUNT,
- onResponse(response, step) {
- addWordReadValues(readValues, step.address, response)
- controlService.applyStatusReadWords(response.words || [], step.address)
- }
- }
- ]
- function splitReadStep(step) {
- const maxQuantity = getMaxReadQuantity(step.functionCode)
- if (!maxQuantity || step.quantity <= maxQuantity) return [step]
- const chunks = []
- let offset = 0
- while (offset < step.quantity) {
- const quantity = Math.min(step.quantity - offset, maxQuantity)
- const address = step.address + offset
- chunks.push({
- ...step,
- address,
- label: `${step.label} ${address.toString(16).toUpperCase()}-${(address + quantity - 1).toString(16).toUpperCase()}`,
- quantity
- })
- offset += quantity
- }
- return chunks
- }
- let syncing = false
- const subscribers = []
- function getState() {
- return {
- isSyncing: syncing,
- syncVersion: paramsSnapshotVersion
- }
- }
- function notify() {
- const state = getState()
- subscribers.slice().forEach((subscriber) => {
- subscriber(state)
- })
- }
- function setSyncing(value) {
- syncing = !!value
- notify()
- }
- transport.subscribe((transportState) => {
- if (!transportState.connectedDevice && syncing) {
- setSyncing(false)
- }
- })
- function subscribe(subscriber) {
- if (typeof subscriber !== 'function') return () => {}
- subscribers.push(subscriber)
- subscriber(getState())
- return () => {
- const index = subscribers.indexOf(subscriber)
- if (index >= 0) subscribers.splice(index, 1)
- }
- }
- function getSharedSlaveAddress() {
- try {
- return transport.getSlaveAddress()
- } catch (error) {
- transport.showCommandAlert('从机地址错误', error.message)
- return null
- }
- }
- function resetReadValues() {
- readValues.coils = {}
- readValues.words = {}
- }
- function getParamsSnapshot() {
- return {
- ...paramsSnapshot,
- syncVersion: paramsSnapshotVersion
- }
- }
- async function syncAllRegisters() {
- if (syncing) return false
- const transportState = transport.getState()
- if (!transportState.connectedDevice) return false
- const slaveAddress = getSharedSlaveAddress()
- if (slaveAddress === null) return false
- setSyncing(true)
- resetReadValues()
- try {
- for (const step of READ_STEPS) {
- for (const chunk of splitReadStep(step)) {
- const response = await transport.sendManagedFrame(
- buildReadFrame(slaveAddress, chunk.functionCode, chunk.address, chunk.quantity),
- chunk.label,
- {
- address: chunk.address,
- functionCode: chunk.functionCode,
- kind: 'sync-read',
- quantity: chunk.quantity,
- slaveAddress
- }
- )
- if (!response) return false
- if (typeof chunk.onResponse === 'function') {
- chunk.onResponse(response, chunk)
- }
- }
- }
- paramsSnapshot = paramsPageState.applyReadValues(paramsSnapshot, readValues)
- paramsSnapshotVersion += 1
- notify()
- notifyPageToast('同步完成')
- return true
- } finally {
- setSyncing(false)
- }
- }
- module.exports = {
- getParamsSnapshot,
- getState,
- subscribe,
- syncAllRegisters
- }
|