| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459 |
- const {
- controlState
- } = require('../../domain/motor-control/data.js')
- const {
- parseHexInteger
- } = require('../../utils/base-utils.js')
- const transport = require('../../transport/ble-core.js')
- const bootloaderService = require('../bootloader/service.js')
- const settingsService = require('../../store/settings-store.js')
- const modbusClient = require('../../protocols/modbus-rtu/client.js')
- const motorControlProtocol = require('./protocol-service.js')
- let state = {
- ...controlState.createInitialState(),
- ...bootloaderService.getState()
- }
- let autoReadTimer = null
- let unsubscribeSettings = null
- let unsubscribeTransport = null
- const subscribers = []
- function getState() {
- return {
- ...state
- }
- }
- function notify() {
- const nextState = getState()
- subscribers.slice().forEach((subscriber) => {
- subscriber(nextState)
- })
- }
- function setState(changedData) {
- state = {
- ...state,
- ...changedData
- }
- notify()
- }
- function applySettingsState(settings) {
- const autoReadInterval = controlState.clampNumber(
- settings.statusPollInterval,
- controlState.AUTO_READ_MIN_INTERVAL,
- controlState.AUTO_READ_MAX_INTERVAL,
- state.autoReadInterval
- )
- const userStatusCount = controlState.getUserStatusCount(settings.userStatusCount)
- setState({
- autoReadInterval,
- userStatusCount
- })
- if (state.autoReadStatus) {
- scheduleAutoReadStatus(autoReadInterval)
- }
- }
- 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 init() {
- transport.init()
- bootloaderService.init()
- settingsService.init()
- if (!unsubscribeSettings) {
- unsubscribeSettings = settingsService.subscribe(applySettingsState)
- }
- if (unsubscribeTransport) return
- unsubscribeTransport = transport.subscribe((transportState) => {
- const nextState = controlState.applyTransportState(state, transportState)
- if (nextState.autoReadStatus === false) {
- stopAutoReadStatus()
- }
- setState(nextState)
- })
- bootloaderService.subscribe((bootloaderState) => {
- setState(bootloaderState)
- })
- }
- function syncSharedInputs() {
- controlState.setSharedInputValues(state.motorParameterInputRegisters)
- }
- function applyControlReadValues(coilValues) {
- setState(controlState.applyControlReadValues(state, coilValues))
- }
- function applyMotorReadWords(words, startAddress = controlState.MOTOR_PARAM_START_ADDRESS) {
- const registerWordCache = controlState.getRegisterWordCache(startAddress, words)
- const motorState = controlState.applyMotorParameterReadValues(state, registerWordCache)
- const nextState = {
- ...state,
- ...motorState
- }
- setState({
- ...motorState,
- ...controlState.applySpeedCommandReadValue(nextState, registerWordCache[0x68])
- })
- }
- function applyDriverReadWords(words) {
- const changedState = controlState.applyDriverParameterReadValues(state, words)
- if (changedState.chipModel) {
- bootloaderService.setChipModel(changedState.chipModel)
- }
- setState(changedState)
- }
- function applyStatusReadWords(words, startAddress = controlState.STATUS_START_ADDRESS) {
- setState(controlState.applyStatusReadValues(words, startAddress))
- }
- function updateMotorParameterInput(index, value) {
- setState(controlState.applyMotorParameterInput(state, index, value))
- }
- function updateMotorParameterBlur(index, value) {
- setState(controlState.applyMotorParameterBlur(state, index, value))
- }
- function updateSpeedCommandInput(value) {
- setState(controlState.applySpeedCommandInput(state, value))
- }
- function updateSpeedCommandBlur(value) {
- setState(controlState.applySpeedCommandBlur(state, value))
- sendSpeedCommand()
- }
- function getSpeedCommandWriteWord() {
- const writeValue = Number(state.speedCommand.writeValue)
- if (!Number.isFinite(writeValue)) return null
- const word = Math.round(writeValue)
- return word >= 0 && word <= 0xFFFF ? word : null
- }
- async function sendSpeedCommand() {
- const slaveAddress = modbusClient.getSharedSlaveAddress()
- if (slaveAddress === null) return false
- const writeWord = getSpeedCommandWriteWord()
- if (writeWord === null) {
- transport.showCommandAlert('转速命令错误', '请检查转速命令输入值')
- return false
- }
- const address = parseHexInteger(state.speedCommand.address)
- const response = await modbusClient.writeSingleRegister(
- slaveAddress,
- address,
- writeWord,
- '转速命令',
- 'speed-command-write'
- )
- if (response) {
- setState({
- ...controlState.clearSpeedCommandDirty(state),
- systemTip: '转速命令已下发'
- })
- return true
- }
- return false
- }
- async function sendControlCommand(key) {
- const button = state.controlButtons
- .concat(state.controlActionButtons || [])
- .find((item) => item.key === key)
- if (!button) return
- const response = await motorControlProtocol.writeControlButton(
- button,
- {
- kind: 'control-write'
- }
- )
- if (response) {
- setState(controlState.applyControlSuccess(state, button))
- }
- }
- async function readControlStatus() {
- const slaveAddress = modbusClient.getSharedSlaveAddress()
- if (slaveAddress === null) return false
- const startAddress = 0x00
- const quantity = 3
- const coilValues = await modbusClient.readBitValues(
- slaveAddress,
- 0x01,
- startAddress,
- quantity,
- '控制状态读取',
- 'control-status-read'
- )
- if (!coilValues) return false
- setState({
- ...controlState.applyControlReadValues(state, coilValues),
- systemTip: '控制状态读取完成'
- })
- return true
- }
- async function readMotorParameters() {
- if (state.isReadingMotor) return
- const slaveAddress = modbusClient.getSharedSlaveAddress()
- if (slaveAddress === null) return
- setState({
- errorText: '',
- isReadingMotor: true,
- systemTip: ''
- })
- try {
- const words = await modbusClient.readRegisterWords(
- slaveAddress,
- 0x03,
- controlState.MOTOR_PARAM_START_ADDRESS,
- controlState.MOTOR_PARAM_WORD_COUNT,
- '电机参数读取',
- 'motor-main-read',
- { showModal: true }
- )
- if (!words) return
- const registerWordCache = controlState.getRegisterWordCache(controlState.MOTOR_PARAM_START_ADDRESS, words)
- setState({
- ...controlState.applyMotorParameterReadValues(state, registerWordCache),
- systemTip: '电机参数读取完成'
- })
- } finally {
- setState({
- isReadingMotor: false
- })
- }
- }
- async function writeMotorParameters() {
- if (state.isWritingMotor) return
- const slaveAddress = modbusClient.getSharedSlaveAddress()
- if (slaveAddress === null) return
- const mainWrite = controlState.buildMotorMainWriteValues(state)
- if (!mainWrite.values) {
- transport.showCommandAlert('参数错误', mainWrite.errorText)
- return
- }
- setState({
- errorText: '',
- isWritingMotor: true,
- systemTip: ''
- })
- try {
- const mainResponse = await modbusClient.writeMultipleRegisters(
- slaveAddress,
- controlState.MOTOR_PARAM_START_ADDRESS,
- mainWrite.values,
- '电机参数写入',
- 'motor-main-write'
- )
- if (!mainResponse) return
- setState({
- ...controlState.clearMotorParameterDirty(state),
- systemTip: '电机参数写入完成'
- })
- } finally {
- setState({
- isWritingMotor: false
- })
- }
- }
- async function readDriverParameters() {
- if (state.isReadingDriver) return
- const slaveAddress = modbusClient.getSharedSlaveAddress()
- if (slaveAddress === null) return
- setState({
- errorText: '',
- isReadingDriver: true,
- systemTip: ''
- })
- try {
- const words = await modbusClient.readRegisterWords(
- slaveAddress,
- 0x04,
- controlState.DRIVER_PARAM_START_ADDRESS,
- controlState.DRIVER_PARAM_WORD_COUNT,
- '驱动器参数读取',
- 'driver-read',
- { showModal: true }
- )
- if (words) {
- const changedState = controlState.applyDriverParameterReadValues(state, words)
- if (changedState.chipModel) {
- bootloaderService.setChipModel(changedState.chipModel)
- }
- setState({
- ...changedState,
- systemTip: '驱动器参数读取完成'
- })
- }
- } finally {
- setState({
- isReadingDriver: false
- })
- }
- }
- function chooseFirmwareFile(source) {
- return bootloaderService.chooseFirmwareFile(source)
- }
- function startFirmwareUpgrade() {
- stopAutoReadStatus()
- setState({
- autoReadStatus: false
- })
- return bootloaderService.startUpgrade()
- }
- function readProgramChecksum() {
- return bootloaderService.readProgramChecksum()
- }
- function handshakeBootloader() {
- return bootloaderService.sendHandshakeKeepAlive()
- }
- function exitBootloader() {
- return bootloaderService.exitBootloader()
- }
- function setAutoReadStatus(autoReadStatus) {
- setState({
- autoReadStatus
- })
- if (autoReadStatus) {
- scheduleAutoReadStatus(0)
- return
- }
- stopAutoReadStatus()
- }
- async function readStatus(options = {}) {
- if (options.auto && !state.connectedDevice) return false
- const slaveAddress = modbusClient.getSharedSlaveAddress()
- if (slaveAddress === null) return false
- const words = await modbusClient.readRegisterWords(
- slaveAddress,
- 0x04,
- controlState.STATUS_START_ADDRESS,
- controlState.getStatusWordCount(state.userStatusCount),
- '状态读取',
- 'status-read',
- { showModal: !options.auto }
- )
- if (words) {
- setState({
- ...controlState.applyStatusReadValues(words, controlState.STATUS_START_ADDRESS),
- systemTip: options.auto ? '' : '状态读取完成'
- })
- }
- return words
- }
- function scheduleAutoReadStatus(delay) {
- stopAutoReadStatus()
- autoReadTimer = setTimeout(async () => {
- if (!state.autoReadStatus) return
- await readStatus({
- auto: true
- })
- scheduleAutoReadStatus(state.autoReadInterval)
- }, delay)
- }
- function stopAutoReadStatus() {
- if (!autoReadTimer) return
- clearTimeout(autoReadTimer)
- autoReadTimer = null
- }
- module.exports = {
- getState,
- init,
- applyControlReadValues,
- applyDriverReadWords,
- applyMotorReadWords,
- applyStatusReadWords,
- exitBootloader,
- handshakeBootloader,
- readControlStatus,
- readDriverParameters,
- readMotorParameters,
- readProgramChecksum,
- readStatus,
- sendControlCommand,
- setAutoReadStatus,
- chooseFirmwareFile,
- startFirmwareUpgrade,
- subscribe,
- syncSharedInputs,
- updateMotorParameterBlur,
- updateMotorParameterInput,
- updateSpeedCommandBlur,
- updateSpeedCommandInput,
- writeMotorParameters
- }
|