Browse Source

BackendMessageReceiver / FrontendMessagePushService

master
修宁 6 months ago
parent
commit
b208c76161
  1. 2
      src/core/engine/Viewport.ts
  2. 178
      src/core/manager/BackendMessageReceiver.ts
  3. 6
      src/core/manager/EnvManager.ts
  4. 4
      src/core/manager/WorldModel.ts
  5. 12
      src/core/script/LCCScript.ts
  6. 13
      src/editor/widgets/IWidgets.ts
  7. 1
      src/editor/widgets/logger/LoggerView.vue
  8. 491
      src/editor/widgets/monitor/MonitorView.vue
  9. 1
      src/editor/widgets/task/TaskView.vue
  10. 92
      src/types/LCC.d.ts
  11. 1
      src/types/ModelTypes.ts

2
src/core/engine/Viewport.ts

@ -27,7 +27,7 @@ import { MapControls } from 'three/examples/jsm/controls/MapControls'
import ModelManager from '@/core/script/ModelManager.ts'
import RuntimeManager from '@/core/manager/RuntimeManager.ts'
import EnvManager from '@/core/manager/EnvManager.ts'
import LccMqttManager from '@/core/manager/LccMqttManager.ts'
import BackendMessageReceiver from '@/core/manager/BackendMessageReceiver.ts'
/**
*

178
src/core/manager/LccMqttManager.ts → src/core/manager/BackendMessageReceiver.ts

@ -8,9 +8,6 @@ export interface MqttMessage {
payload: Buffer | string
}
// 定义MQTT消息处理器
export type MqttMessageHandler = (message: MqttMessage) => void
// 定义MQTT连接状态
enum ConnectionStatus {
DISCONNECTED = 'disconnected',
@ -20,12 +17,21 @@ enum ConnectionStatus {
ERROR = 'error'
}
type ProcessFn = (message: MqttMessage, handler: BackendMessageHandler) => void
interface HandlerNode {
processFn: ProcessFn
handler: BackendMessageHandler
}
/**
*
*/
export default class LccMqttManager {
export default class BackendMessageReceiver {
private projectUuid: string
private envId: number
private client: mqtt.MqttClient | null = null
private handlers: Map<string, MqttMessageHandler[]> = new Map()
private handlers: Map<string, HandlerNode[]> = new Map()
// 状态管理
public state = reactive({
@ -37,7 +43,7 @@ export default class LccMqttManager {
})
// 启动MQTT连接
public async start(config: MqttConfig): Promise<boolean> {
public async start(projectUuid: string, envId: number, config: MqttConfig): Promise<boolean> {
// 如果已经连接,先断开
if (this.client?.connected) {
await this.dispose()
@ -123,21 +129,50 @@ export default class LccMqttManager {
})
}
public getTopicStringByType(type: BackendTopicType): [string, ProcessFn] {
// 根据类型生成订阅的 topic 字符串
const projId = this.projectUuid
const envId = this.envId
switch (type) {
case 'ServerState':
return [`lcc/${projId}/${envId}/server`, this.handleServerState]
case 'ClientState':
return [`lcc/${projId}/${envId}/client`, this.handleClientState]
case 'TaskUpdate':
return [`lcc/${projId}/${envId}/task`, this.handleTaskMonitor]
case 'InvUpdate':
return [`lcc/${projId}/${envId}/inv/#`, this.handleInventoryMonitor]
case 'DeviceStatus':
return [`lcc/${projId}/${envId}/device/+/status`, this.handleDeviceStatus]
case 'DeviceAlive':
return [`lcc/${projId}/${envId}/device/+/alive`, this.handleDeviceAlive]
case 'Logs':
return [`lcc/${projId}/${envId}/log/#`, this.handleLogMonitor]
case 'Alarm':
return [`lcc/${projId}/${envId}/alarm`, this.handleAlarmMonitor]
case 'ScriptUpdate':
return [`lcc/${projId}/script`, this.handleScriptSystem]
}
throw new Error(`Invalid topic for type ${type}`)
}
// 订阅主题
public subscribe(topic: string, handler: MqttMessageHandler): void {
public subscribe(type: BackendTopicType, handler: BackendMessageHandler): void {
if (!this.client?.connected) {
console.warn('Cannot subscribe - MQTT not connected')
return
throw new Error('Cannot subscribe - MQTT not connected')
}
const [topic, processFn] = this.getTopicStringByType(type)
// 添加消息处理器
if (!this.handlers.has(topic)) {
this.handlers.set(topic, [])
}
this.handlers.get(topic)?.push(handler)
this.handlers.get(topic)?.push({ processFn, handler })
// 如果尚未订阅该主题
if (!this.state.subscribedTopics.includes(topic)) {
if (!this.state.subscribedTopics.includes(topic) && this.client) {
const options: IClientSubscribeOptions = { qos: 1 }
this.client.subscribe(topic, options, (err) => {
@ -152,16 +187,20 @@ export default class LccMqttManager {
}
// 取消订阅
public unsubscribe(topic: string, handler?: MqttMessageHandler): void {
if (!this.client?.connected) {
console.warn('Cannot unsubscribe - MQTT not connected')
return
public unsubscribe(type: BackendTopicType, handler: BackendMessageHandler): void {
// if (!this.client?.connected) {
// throw new Error('Cannot unsubscribe - MQTT not connected')
// }
const [topic, processFn] = this.getTopicStringByType(type)
if (!topic) {
throw new Error(`Invalid topic for type ${type}`)
}
// 移除特定处理函数
if (handler && this.handlers.has(topic)) {
const handlers = this.handlers.get(topic) || []
const newHandlers = handlers.filter(h => h !== handler)
const newHandlers = handlers.filter(h => (h.processFn !== processFn && h.handler !== handler))
if (newHandlers.length > 0) {
this.handlers.set(topic, newHandlers)
@ -173,7 +212,7 @@ export default class LccMqttManager {
}
// 如果没有处理器了,取消订阅
if (!this.handlers.has(topic)) {
if (!this.handlers.has(topic) && this.client) {
this.client.unsubscribe(topic, {}, (err) => {
if (err) {
console.error(`Failed to unsubscribe from ${topic}:`, err)
@ -191,7 +230,12 @@ export default class LccMqttManager {
// 1. 查找该主题的精确匹配处理器
if (this.handlers.has(topic)) {
this.handlers.get(topic)?.forEach(handler => handler(message))
this.handlers.get(topic)?.forEach(node => {
const { processFn, handler } = node
processFn(message, handler)
})
}
// 2. 查找通配符匹配的处理器
@ -199,7 +243,12 @@ export default class LccMqttManager {
for (const pattern of wildcardTopics) {
if (this.matchTopic(pattern, topic)) {
this.handlers.get(pattern)?.forEach(handler => handler(message))
this.handlers.get(pattern)?.forEach(node => {
const { processFn, handler } = node
processFn(message, handler)
})
}
}
}
@ -232,129 +281,98 @@ export default class LccMqttManager {
return patternParts.length === topicParts.length
}
// 注册LCC监控处理器
public registerLccHandlers(projId: string, envId: string) {
// 服务器状态监控
this.subscribe(`lcc/${projId}/${envId}/server`, this.handleServerState)
// 客户端状态监控
this.subscribe(`lcc/${projId}/${envId}/client`, this.handleClientState)
// 任务监控
this.subscribe(`lcc/${projId}/${envId}/task`, this.handleTaskMonitor)
// 库存监控
this.subscribe(`lcc/${projId}/${envId}/inv/#`, this.handleInventoryMonitor)
// 设备监控
this.subscribe(`lcc/${projId}/${envId}/device/+/status`, this.handleDeviceStatus)
this.subscribe(`lcc/${projId}/${envId}/device/+/alive`, this.handleDeviceAlive)
// 日志监控
this.subscribe(`lcc/${projId}/${envId}/log/#`, this.handleLogMonitor)
// 告警监控
this.subscribe(`lcc/${projId}/${envId}/alarm`, this.handleAlarmMonitor)
// 脚本系统
this.subscribe(`lcc/${projId}/script`, this.handleScriptSystem)
}
// ==================== 消息处理器实现 ====================
private handleServerState(message: MqttMessage) {
private handleServerState(message: MqttMessage, handler: BackendMessageHandler) {
try {
const data = JSON.parse(message.payload.toString())
console.log('Server state update:', data)
// 这里可以分发到Vue store或其他状态管理系统
handler('ServerState', message.topic, _.cloneDeep(data))
} catch (error) {
console.error('Error parsing server state:', error)
}
}
private handleClientState(message: MqttMessage) {
private handleClientState(message: MqttMessage, handler: BackendMessageHandler) {
try {
const data = JSON.parse(message.payload.toString())
console.log('Client state update:', data)
// 处理客户端状态更新
handler('ClientState', message.topic, _.cloneDeep(data))
} catch (error) {
console.error('Error parsing client state:', error)
}
}
private handleTaskMonitor(message: MqttMessage) {
private handleTaskMonitor(message: MqttMessage, handler: BackendMessageHandler) {
try {
const taskData = JSON.parse(message.payload.toString())
console.log('Task update:', taskData)
// 处理任务更新
const data = JSON.parse(message.payload.toString())
handler('TaskUpdate', message.topic, _.cloneDeep(data))
} catch (error) {
console.error('Error parsing task data:', error)
}
}
private handleInventoryMonitor(message: MqttMessage) {
private handleInventoryMonitor(message: MqttMessage, handler: BackendMessageHandler) {
try {
const [projId, envId, inv, catalogCode] = message.topic.split('/')
const inventoryData = JSON.parse(message.payload.toString())
const data = JSON.parse(message.payload.toString())
handler('InvUpdate', message.topic, _.cloneDeep(data))
console.log(`Inventory update for ${catalogCode}:`, inventoryData)
// 处理库存更新
} catch (error) {
console.error('Error parsing inventory data:', error)
}
}
private handleDeviceStatus(message: MqttMessage) {
private handleDeviceStatus(message: MqttMessage, handler: BackendMessageHandler) {
try {
const [, projId, envId, device, deviceId, status] = message.topic.split('/')
const deviceData = JSON.parse(message.payload.toString())
const data = JSON.parse(message.payload.toString())
handler('DeviceStatus', message.topic, _.cloneDeep(data))
console.log(`Device status for ${deviceId}:`, deviceData)
// 处理设备状态更新
} catch (error) {
console.error('Error parsing device status:', error)
}
}
private handleDeviceAlive(message: MqttMessage) {
private handleDeviceAlive(message: MqttMessage, handler: BackendMessageHandler) {
try {
const [, projId, envId, device, deviceId, alive] = message.topic.split('/')
const status = message.payload.toString()
const data = JSON.parse(message.payload.toString())
handler('DeviceAlive', message.topic, _.cloneDeep(data))
console.log(`Device ${deviceId} is ${status}`)
// 处理设备存活状态
} catch (error) {
console.error('Error parsing device alive status:', error)
}
}
private handleLogMonitor(message: MqttMessage) {
private handleLogMonitor(message: MqttMessage, handler: BackendMessageHandler) {
try {
const [, projId, envId, log, logType] = message.topic.split('/')
const logData = JSON.parse(message.payload.toString())
const data = JSON.parse(message.payload.toString())
handler('Logs', message.topic, _.cloneDeep(data))
console.log(`Logs for ${logType}:`, logData)
// 处理日志更新
} catch (error) {
console.error('Error parsing log data:', error)
}
}
private handleAlarmMonitor(message: MqttMessage) {
private handleAlarmMonitor(message: MqttMessage, handler: BackendMessageHandler) {
try {
const alarmData = JSON.parse(message.payload.toString())
console.log('Alarm update:', alarmData)
// 处理告警更新
const data = JSON.parse(message.payload.toString())
handler('Alarm', message.topic, _.cloneDeep(data))
} catch (error) {
console.error('Error parsing alarm data:', error)
}
}
private handleScriptSystem(message: MqttMessage) {
private handleScriptSystem(message: MqttMessage, handler: BackendMessageHandler) {
try {
const scriptData = JSON.parse(message.payload.toString())
console.log('Script system update:', scriptData)
// 处理脚本系统更新
const data = JSON.parse(message.payload.toString())
handler('ScriptUpdate', message.topic, _.cloneDeep(data))
} catch (error) {
console.error('Error parsing script data:', error)
}

6
src/core/manager/EnvManager.ts

@ -2,7 +2,6 @@ import type Viewport from '@/core/engine/Viewport.ts'
import { worldModel } from '@/core/manager/WorldModel.ts'
import mqtt, { type IConnackPacket, type IPublishPacket } from 'mqtt'
import type { ErrorWithReasonCode } from 'mqtt/src/lib/shared.ts'
import type Cl23dObject from '@/modules/cl2/Cl23dObject.ts'
import { Request } from '@ease-forge/shared'
import AmrMessageManager from '@/core/manager/amr/AmrMessageManager'
import { AmrMsg } from '@/core/manager/amr/AmrMessageDefine'
@ -63,7 +62,10 @@ export default class EnvManager {
worldModel.state.runState.currentEnv = env
try {
await LCC.serverStart()
await worldModel.lccMqttManager.start(env.envConfig.frontendMqtt)
await worldModel.backendMessageReceiver.start(
worldModel.state.project_uuid,
worldModel.state.runState.currentEnvId,
env.envConfig.frontendMqtt)
await LCC.loadInv()
this.client = mqtt.connect(env.envConfig.mqtt.websocket, {

4
src/core/manager/WorldModel.ts

@ -5,7 +5,7 @@ import EventBus from '@/runtime/EventBus'
import StateManager from '@/core/manager/StateManager.ts'
import { getQueryParams, setQueryParam } from '@/utils/webutils.ts'
import localforage from 'localforage'
import LccMqttManager from '@/core/manager/LccMqttManager.ts'
import BackendMessageReceiver from '@/core/manager/BackendMessageReceiver.ts'
import EnvManager from '@/core/manager/EnvManager.ts'
import RCSScript from '@/core/script/RCSScript.ts'
import LCCScript from '@/core/script/LCCScript.ts'
@ -40,7 +40,7 @@ export interface WorldModelState {
*/
export default class WorldModel {
currentStateManager: StateManager
lccMqttManager = new LccMqttManager()
backendMessageReceiver = new BackendMessageReceiver()
envManager = new EnvManager()
/**

12
src/core/script/LCCScript.ts

@ -1,4 +1,4 @@
import Viewport from '@/core/engine/Viewport.ts'
import _ from 'lodash'
import { worldModel } from '@/core/manager/WorldModel.ts'
import { Request } from '@ease-forge/shared'
@ -67,7 +67,7 @@ export default class LCCScript implements LCC {
}
// 从后台读取所有车
async loadExecutor(): Promise<ServerResponse<ExecutorVo>> {
async loadExecutor(): Promise<ExecutorVo> {
const res = await Request.request.post('/api/workbench/LccController@loadExecutor', {
projectUuid: worldModel.state.project_uuid,
envId: worldModel.state.runState.currentEnvId
@ -112,4 +112,12 @@ export default class LCCScript implements LCC {
return res.data
}
subscribe(topicType: BackendTopicType, eventHandler: BackendMessageHandler) {
worldModel.backendMessageReceiver.subscribe(topicType, eventHandler)
}
unsubscribe(topicType: BackendTopicType, eventHandler: BackendMessageHandler) {
worldModel.backendMessageReceiver.unsubscribe(topicType, eventHandler)
}
}

13
src/editor/widgets/IWidgets.ts

@ -1,6 +1,7 @@
import { defineComponent } from 'vue'
import { renderIcon } from '@/utils/webutils.js'
import Viewport, { type ViewportState } from '@/core/engine/Viewport.ts'
import { worldModel } from '@/core/manager/WorldModel.ts'
export type IWidgetData = {
/**
@ -23,6 +24,18 @@ export default defineComponent({
computed: {
state(): ViewportState {
return this.viewport?.state
},
errorDescription() {
if (!this.isActivated) {
return '组件未激活'
}
if (!worldModel.state.isOpened) {
return '地图未打开'
}
if (!worldModel.backendMessageReceiver.state.isConnected) {
return '后端连接异常'
}
return ''
}
},
emits: ['close'],

1
src/editor/widgets/logger/LoggerView.vue

@ -21,7 +21,6 @@ import YvSrcEditor from '@/components/YvSrcEditor.vue'
export default {
name: 'LoggerView',
components: { YvSrcEditor },
webSocketSubscribe: ['logs'],
mixins: [IWidgets],
data() {
return {

491
src/editor/widgets/monitor/MonitorView.vue

@ -11,26 +11,28 @@
</span>
</div>
<div class="calc-left-panel">
<div class="monitor-tool-wrap">
<el-empty v-if="!isActivated || errorDescription" :description="errorDescription">
</el-empty>
<div v-else class="monitor-tool-wrap">
<div class="infor-row">
<div class="infor-item">
总数<span class="num">{{total}}</span>
总数<span class="num">{{ total }}</span>
</div>
<div class="infor-item">
上线<span class="num num-red">{{online}}</span>
上线<span class="num num-red">{{ online }}</span>
</div>
<div class="infor-item">
下线<span class="num num-green">{{offline}}</span>
下线<span class="num num-green">{{ offline }}</span>
</div>
<div class="infor-item">
运行中<span class="num num-blue">{{running}}</span>
运行中<span class="num num-blue">{{ running }}</span>
</div>
<div class="infor-item">
空闲中<span class="num num-orange">{{idle}}</span>
空闲中<span class="num num-orange">{{ idle }}</span>
</div>
</div>
<div class="list">
<div class="item">
<div v-for="deviceInfo in deviceList" class="item" :class="selectedId === deviceInfo.id" @click="()=>{selectedId = deviceInfo.id}">
<div class="content">
<div class="row">
<div class="row-icon">
@ -38,10 +40,16 @@
</div>
<div class="row-content">
<div class="data-infor">
<svg t="1751447150651" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7400" width="16" height="16"><path d="M426.666667 85.333333a42.666667 42.666667 0 0 1 42.666666 42.666667v298.666667a42.666667 42.666667 0 0 1-42.666666 42.666666H128a42.666667 42.666667 0 0 1-42.666667-42.666666V128a42.666667 42.666667 0 0 1 42.666667-42.666667h298.666667z m42.666666 512a42.666667 42.666667 0 0 0-42.666666-42.666666H128a42.666667 42.666667 0 0 0-42.666667 42.666666v298.666667a42.666667 42.666667 0 0 0 42.666667 42.666667h298.666667a42.666667 42.666667 0 0 0 42.666666-42.666667v-298.666667z m469.333334 0a42.666667 42.666667 0 0 0-42.666667-42.666666h-298.666667a42.666667 42.666667 0 0 0-42.666666 42.666666v298.666667a42.666667 42.666667 0 0 0 42.666666 42.666667h298.666667a42.666667 42.666667 0 0 0 42.666667-42.666667v-298.666667zM384 640H170.666667v213.333333h213.333333v-213.333333z m256 0h213.333333v213.333333h-213.333333v-213.333333z m298.666667-512a42.666667 42.666667 0 0 0-42.666667-42.666667h-298.666667a42.666667 42.666667 0 0 0-42.666666 42.666667v298.666667a42.666667 42.666667 0 0 0 42.666666 42.666666h298.666667a42.666667 42.666667 0 0 0 42.666667-42.666666V128zM384 170.666667H170.666667v213.333333h213.333333V170.666667z m256 0h213.333333v213.333333h-213.333333V170.666667z" fill="#ffffff" p-id="7401"></path></svg>
<span class="green">[运行]</span>
<svg t="1751447150651" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7400" width="16" height="16">
<path
d="M426.666667 85.333333a42.666667 42.666667 0 0 1 42.666666 42.666667v298.666667a42.666667 42.666667 0 0 1-42.666666 42.666666H128a42.666667 42.666667 0 0 1-42.666667-42.666666V128a42.666667 42.666667 0 0 1 42.666667-42.666667h298.666667z m42.666666 512a42.666667 42.666667 0 0 0-42.666666-42.666666H128a42.666667 42.666667 0 0 0-42.666667 42.666666v298.666667a42.666667 42.666667 0 0 0 42.666667 42.666667h298.666667a42.666667 42.666667 0 0 0 42.666666-42.666667v-298.666667z m469.333334 0a42.666667 42.666667 0 0 0-42.666667-42.666666h-298.666667a42.666667 42.666667 0 0 0-42.666666 42.666666v298.666667a42.666667 42.666667 0 0 0 42.666666 42.666667h298.666667a42.666667 42.666667 0 0 0 42.666667-42.666667v-298.666667zM384 640H170.666667v213.333333h213.333333v-213.333333z m256 0h213.333333v213.333333h-213.333333v-213.333333z m298.666667-512a42.666667 42.666667 0 0 0-42.666667-42.666667h-298.666667a42.666667 42.666667 0 0 0-42.666666 42.666667v298.666667a42.666667 42.666667 0 0 0 42.666666 42.666666h298.666667a42.666667 42.666667 0 0 0 42.666667-42.666666V128zM384 170.666667H170.666667v213.333333h213.333333V170.666667z m256 0h213.333333v213.333333h-213.333333V170.666667z"
fill="#ffffff" p-id="7401"></path>
</svg>
<span class="green">[{{ getDeviceModeDesc(deviceInfo) }}]</span>
<span>导航到
<svg t="1751450118989" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="22184" width="15" height="15"><path d="M926.784 97.216v829.568H97.216V97.216h829.568z m-56.896 56.832H154.048v715.84h715.84V154.048z m-101.504 61.312l40.256 40.256L615.68 448.512v126.976l192.96 192.896-40.256 40.256L575.488 615.68H448.512l-192.896 192.96-40.256-40.256L408.32 575.552V448.448L215.36 255.616l40.256-40.256L448.448 408.32h127.104l192.832-192.896z" p-id="22185" fill="#ffffff"></path></svg>
<svg t="1751450118989" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="22184" width="15" height="15"><path
d="M926.784 97.216v829.568H97.216V97.216h829.568z m-56.896 56.832H154.048v715.84h715.84V154.048z m-101.504 61.312l40.256 40.256L615.68 448.512v126.976l192.96 192.896-40.256 40.256L575.488 615.68H448.512l-192.896 192.96-40.256-40.256L408.32 575.552V448.448L215.36 255.616l40.256-40.256L448.448 408.32h127.104l192.832-192.896z"
p-id="22185" fill="#ffffff"></path></svg>
</span>
<div class="progress">
<span :style="{width:'55%'}"></span>
@ -49,87 +57,34 @@
</div>
</div>
<div class="data-infor">
<svg t="1751448794644" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2439" width="16" height="16"><path d="M859.9104 609.92512l0 45.6c-0.67968 2.21952-1.5104 4.4352-1.9648 6.70464-4.66048 24.09984-7.28448 48.82944-14.31552 72.22016-20.84992 69.02016-59.92064 126.53952-114.6944 173.50016-42.24512 36.2496-89.7856 62.36544-144.1344 75.22048-17.87008 4.23552-36.19456 6.73024-54.32064 10.0352l-45.5744 0c-2.21952-0.6848-4.49024-1.72032-6.75456-1.87008-48.12544-2.9952-93.72544-15.52512-136.50048-37.38496-80.86528-41.18528-139.19488-102.5152-165.83552-190.74048-5.67424-18.8544-8.03968-38.62016-11.9744-57.97504l0-43.50976c1.7152-10.69056 3.2-21.47456 5.21984-32.16 8.61952-46.68544 29.36576-88.0256 56.83968-126.19008 25.91488-35.92064 53.44-70.70464 78.016-107.53536 26.56896-39.95008 39.424-84.2944 31.88992-132.9152-1.4848-9.60512-2.87488-19.20896-4.33536-28.76416 0.98048-0.25088 1.9648-0.45056 2.9504-0.73088 59.31008 62.16064 68.96512 138.46528 60.49408 220.92032 2.17088-2.31936 3.98592-3.93472 5.37088-5.79968 50.33984-68.08448 71.96416-143.29984 55.55456-227.54688-10.42944-53.58976-32.99456-101.76512-70.32448-141.81504C369.3056 61.84576 349.69472 47.65568 331.61984 32l18.65472 0c1.536 0.62976 2.976 1.7152 4.53504 1.86496 32.82048 2.81984 63.65056 12.95488 93.02016 27.2 67.17056 32.51584 121.62048 80.58496 167.17056 139.22048 66.9504 86.27968 110.48448 181.99424 119.10528 292.19968 3.30496 42.06976-0.9856 82.95552-12.19968 123.2896-4.23552 15.27552-10.21056 30.04544-15.68 45.94944 21.72544-9.25056 38.24-23.38944 50.9952-41.7152 38.04032-54.77504 48.67456-115.85536 40.05504-183.38048 2.80064 3.24992 4.23552 4.53504 5.21472 6.14528 22.91456 36.19968 40.05504 74.81472 49.0048 116.78464C855.05024 576.17024 857.11488 593.1648 859.9104 609.92512M501.56544 529.61536c-0.85504 0.60544-1.79072 1.2352-2.67008 1.84064-1.18528 16.64-2.06976 33.30048-3.68 49.93536-2.37056 25.38496-8.44544 49.85984-20.32 72.62464-14.52032 27.87968-38.7904 45.21984-65.69088 59.01056-29.00992 14.9696-47.28448 36.34944-49.65504 70.10048-2.46912 34.70976 7.96544 63.86944 35.94496 85.20064 26.21568 19.96032 56.84096 26.4704 89.3056 25.38496 51.82976-1.6896 90.4448-26.32064 105.92512-78.1952 11.11552-37.23008 9.30048-74.71488 1.86496-112.19456-10.16064-51.37536-28.76544-99.26528-60.60032-141.2352C523.04512 550.36032 511.7504 540.40448 501.56544 529.61536" fill="#de833f" p-id="2440"></path></svg>
<div class="infor-right">按照导航路径移动至目标点</div>
<svg t="1751448794644" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2439" width="16" height="16">
<path
d="M859.9104 609.92512l0 45.6c-0.67968 2.21952-1.5104 4.4352-1.9648 6.70464-4.66048 24.09984-7.28448 48.82944-14.31552 72.22016-20.84992 69.02016-59.92064 126.53952-114.6944 173.50016-42.24512 36.2496-89.7856 62.36544-144.1344 75.22048-17.87008 4.23552-36.19456 6.73024-54.32064 10.0352l-45.5744 0c-2.21952-0.6848-4.49024-1.72032-6.75456-1.87008-48.12544-2.9952-93.72544-15.52512-136.50048-37.38496-80.86528-41.18528-139.19488-102.5152-165.83552-190.74048-5.67424-18.8544-8.03968-38.62016-11.9744-57.97504l0-43.50976c1.7152-10.69056 3.2-21.47456 5.21984-32.16 8.61952-46.68544 29.36576-88.0256 56.83968-126.19008 25.91488-35.92064 53.44-70.70464 78.016-107.53536 26.56896-39.95008 39.424-84.2944 31.88992-132.9152-1.4848-9.60512-2.87488-19.20896-4.33536-28.76416 0.98048-0.25088 1.9648-0.45056 2.9504-0.73088 59.31008 62.16064 68.96512 138.46528 60.49408 220.92032 2.17088-2.31936 3.98592-3.93472 5.37088-5.79968 50.33984-68.08448 71.96416-143.29984 55.55456-227.54688-10.42944-53.58976-32.99456-101.76512-70.32448-141.81504C369.3056 61.84576 349.69472 47.65568 331.61984 32l18.65472 0c1.536 0.62976 2.976 1.7152 4.53504 1.86496 32.82048 2.81984 63.65056 12.95488 93.02016 27.2 67.17056 32.51584 121.62048 80.58496 167.17056 139.22048 66.9504 86.27968 110.48448 181.99424 119.10528 292.19968 3.30496 42.06976-0.9856 82.95552-12.19968 123.2896-4.23552 15.27552-10.21056 30.04544-15.68 45.94944 21.72544-9.25056 38.24-23.38944 50.9952-41.7152 38.04032-54.77504 48.67456-115.85536 40.05504-183.38048 2.80064 3.24992 4.23552 4.53504 5.21472 6.14528 22.91456 36.19968 40.05504 74.81472 49.0048 116.78464C855.05024 576.17024 857.11488 593.1648 859.9104 609.92512M501.56544 529.61536c-0.85504 0.60544-1.79072 1.2352-2.67008 1.84064-1.18528 16.64-2.06976 33.30048-3.68 49.93536-2.37056 25.38496-8.44544 49.85984-20.32 72.62464-14.52032 27.87968-38.7904 45.21984-65.69088 59.01056-29.00992 14.9696-47.28448 36.34944-49.65504 70.10048-2.46912 34.70976 7.96544 63.86944 35.94496 85.20064 26.21568 19.96032 56.84096 26.4704 89.3056 25.38496 51.82976-1.6896 90.4448-26.32064 105.92512-78.1952 11.11552-37.23008 9.30048-74.71488 1.86496-112.19456-10.16064-51.37536-28.76544-99.26528-60.60032-141.2352C523.04512 550.36032 511.7504 540.40448 501.56544 529.61536"
fill="#de833f" p-id="2440"></path>
</svg>
<div class="infor-right">{{ getDeviceTaskTypeDesc(deviceInfo) }}</div>
</div>
<div class="data-infor">
<svg t="1751448901466" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5172" width="16" height="16"><path d="M169.6 222.6c0-41.2 33.4-74.7 74.7-74.7H294c0.1 0 0.1 0 0.1-0.1V98.3c0-0.1 0-0.1-0.1-0.1h-49.6c-68.8 0-124.6 55.8-124.6 124.6v49.6c0 0.1 0 0.1 0.1 0.1h49.6c0.1 0 0.1 0 0.1-0.1v-49.8zM791.8 98.2h-49.6c-0.1 0-0.1 0-0.1 0.1v49.6c0 0.1 0 0.1 0.1 0.1h49.7c41.2 0 74.7 33.4 74.7 74.7v49.7c0 0.1 0 0.1 0.1 0.1h49.6c0.1 0 0.1 0 0.1-0.1v-49.6c0-68.9-55.8-124.6-124.6-124.6z m74.8 398.2c0-192.5-156-348.5-348.5-348.5S169.6 304 169.6 496.4c0 132 73.4 246.7 181.5 305.9 0.1 0 0.1 0.1 0 0.2l-81.8 92.1c-0.1 0.1 0 0.2 0.1 0.2h74.5l66.8-66.8h0.1c33.8 11 69.9 17 107.4 17s73.5-6.1 107.4-17h0.1l66.8 66.8H767c0.1 0 0.1-0.1 0.1-0.2l-81.8-92.1v-0.2c107.9-59.1 181.3-173.9 181.3-305.9z m-348.4 24.9c-13.8 0-25-11.2-25-25V298c0-14.7 12.1-26.6 26.7-25.5 12.9 0.9 23 11.7 23 24.8v174.2c0 0.1 0 0.1 0.1 0.1h148.6c14.7 0 26.6 12.1 25.5 26.7-0.9 12.9-11.7 23-24.8 23H518.2z" p-id="5173" fill="#edd268"></path></svg>
<div class="infor-right">17 23:00:00 -01 23:00:00</div>
</div>
<div class="data-infor">
<svg t="1751448953457" class="icon" viewBox="0 0 1820 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6479" width="24" height="16"><path d="M383.620741 810.951111c-48.734815 0-88.177778 39.537778-88.177778 88.272593 0 48.734815 39.537778 88.272593 88.177778 88.272592 48.734815 0 88.272593-39.537778 88.272592-88.272592 0-48.734815-39.537778-88.272593-88.272592-88.272593z m288.521481 0c-48.734815 0-88.272593 39.537778-88.272592 88.272593 0 48.734815 39.537778 88.272593 88.272592 88.272592 48.734815 0 88.177778-39.537778 88.177778-88.272592 0-48.734815-39.442963-88.272593-88.177778-88.272593z m462.317037-4.077037c0-5.973333-2.37037-11.757037-6.637037-15.928889-4.266667-4.266667-31.383704-24.082963-37.451852-24.082963h-132.361481V60.681481c0-5.973333-20.574815-33.28-24.841482-37.546666s-10.05037-6.637037-16.118518-6.637037h-68.266667c-6.068148 0-11.851852 2.37037-16.118518 6.637037s-6.637037 9.955556-6.637037 15.928889l-0.474074 639.431111h-21.333334v-44.088889c0-15.928889-32.237037-33.46963-44.088889-44.088889l-94.056296-96.142222c-10.42963-9.481481-24.177778-36.219259-38.305185-36.219259l-44.088889-308.906667c-3.034074-28.728889-14.980741-44.088889-44.088889-44.088889h-243.674074c-31.383704 0-44.088889 12.98963-44.088889 44.088889V457.955556c-31.383704 0-88.272593 57.078519-88.272592 88.272592v308.906667c0 31.194074 12.705185 44.088889 44.088888 44.088889h44.088889c0-71.68 60.112593-132.361481 132.361482-132.361482 72.248889 0 132.361481 60.681481 132.361481 132.361482h22.850371c0-71.68 60.112593-132.361481 132.361481-132.361482 72.248889 0 132.361481 60.681481 132.361482 132.361482h286.34074c6.068148 0 33.185185-4.456296 37.451852-8.628148 4.266667-4.266667 6.637037-29.487407 6.637037-35.460741V806.874074zM489.14963 483.365926c-4.077037 4.551111-9.955556 7.205926-16.023704 7.205926l-21.997037 11.472592V546.133333c0 8.722963 0.474074 44.088889 0 44.088889h-44.088889l-34.133333-0.568889c-8.628148 0-16.971852-3.508148-23.04-9.671111-6.068148-6.162963-9.576296-14.601481-9.576297-23.419259V226.038519c0-18.299259 14.601481-33.09037 32.616297-33.090371h67.128889c16.877037 0 30.90963 12.98963 32.426666 30.056296L494.743704 466.488889c0.568889 6.162963-1.422222 12.325926-5.594074 16.877037z m-38.115556 17.825185c-0.094815-0.18963-0.284444-0.094815-0.474074 0.18963-0.284444 0.18963-0.379259 0.379259-0.18963 0.474074-0.18963 0.568889-0.094815 1.042963 0.853334 0.094815 0.853333-0.853333 0.379259-0.948148-0.18963-0.758519z" p-id="6480" fill="#ffffff"></path></svg>
<svg t="1751448901466" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5172" width="16" height="16">
<path
d="M169.6 222.6c0-41.2 33.4-74.7 74.7-74.7H294c0.1 0 0.1 0 0.1-0.1V98.3c0-0.1 0-0.1-0.1-0.1h-49.6c-68.8 0-124.6 55.8-124.6 124.6v49.6c0 0.1 0 0.1 0.1 0.1h49.6c0.1 0 0.1 0 0.1-0.1v-49.8zM791.8 98.2h-49.6c-0.1 0-0.1 0-0.1 0.1v49.6c0 0.1 0 0.1 0.1 0.1h49.7c41.2 0 74.7 33.4 74.7 74.7v49.7c0 0.1 0 0.1 0.1 0.1h49.6c0.1 0 0.1 0 0.1-0.1v-49.6c0-68.9-55.8-124.6-124.6-124.6z m74.8 398.2c0-192.5-156-348.5-348.5-348.5S169.6 304 169.6 496.4c0 132 73.4 246.7 181.5 305.9 0.1 0 0.1 0.1 0 0.2l-81.8 92.1c-0.1 0.1 0 0.2 0.1 0.2h74.5l66.8-66.8h0.1c33.8 11 69.9 17 107.4 17s73.5-6.1 107.4-17h0.1l66.8 66.8H767c0.1 0 0.1-0.1 0.1-0.2l-81.8-92.1v-0.2c107.9-59.1 181.3-173.9 181.3-305.9z m-348.4 24.9c-13.8 0-25-11.2-25-25V298c0-14.7 12.1-26.6 26.7-25.5 12.9 0.9 23 11.7 23 24.8v174.2c0 0.1 0 0.1 0.1 0.1h148.6c14.7 0 26.6 12.1 25.5 26.7-0.9 12.9-11.7 23-24.8 23H518.2z"
p-id="5173" fill="#edd268"></path>
</svg>
<div class="infor-right">
<span class="blue name">Agv-5 </span>当前目标点 <span class="blue">412</span></div>
</div>
</div>
{{ deviceInfo.isBlocked ? '阻挡' : '' }}
{{ deviceInfo.taskStatus == 'IDLE' ? '空闲' : '' }}
{{ deviceInfo.taskStatus == 'PAUSED' ? '暂停' : '' }}
{{ deviceInfo.taskStatus == 'EXECUTING' ? '执行中' : '' }}
</div>
</div>
</div>
<div class="item selected">
<div class="content">
<div class="row">
<div class="row-icon">
<component :is="renderIcon('antd DeploymentUnitOutlined')"></component>
</div>
<div class="row-content">
<div class="data-infor">
<svg t="1751447150651" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7400" width="16" height="16"><path d="M426.666667 85.333333a42.666667 42.666667 0 0 1 42.666666 42.666667v298.666667a42.666667 42.666667 0 0 1-42.666666 42.666666H128a42.666667 42.666667 0 0 1-42.666667-42.666666V128a42.666667 42.666667 0 0 1 42.666667-42.666667h298.666667z m42.666666 512a42.666667 42.666667 0 0 0-42.666666-42.666666H128a42.666667 42.666667 0 0 0-42.666667 42.666666v298.666667a42.666667 42.666667 0 0 0 42.666667 42.666667h298.666667a42.666667 42.666667 0 0 0 42.666666-42.666667v-298.666667z m469.333334 0a42.666667 42.666667 0 0 0-42.666667-42.666666h-298.666667a42.666667 42.666667 0 0 0-42.666666 42.666666v298.666667a42.666667 42.666667 0 0 0 42.666666 42.666667h298.666667a42.666667 42.666667 0 0 0 42.666667-42.666667v-298.666667zM384 640H170.666667v213.333333h213.333333v-213.333333z m256 0h213.333333v213.333333h-213.333333v-213.333333z m298.666667-512a42.666667 42.666667 0 0 0-42.666667-42.666667h-298.666667a42.666667 42.666667 0 0 0-42.666666 42.666667v298.666667a42.666667 42.666667 0 0 0 42.666666 42.666666h298.666667a42.666667 42.666667 0 0 0 42.666667-42.666666V128zM384 170.666667H170.666667v213.333333h213.333333V170.666667z m256 0h213.333333v213.333333h-213.333333V170.666667z" fill="#ffffff" p-id="7401"></path></svg>
<span class="green">[运行]</span>
<span>导航到
<svg t="1751450118989" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="22184" width="15" height="15"><path d="M926.784 97.216v829.568H97.216V97.216h829.568z m-56.896 56.832H154.048v715.84h715.84V154.048z m-101.504 61.312l40.256 40.256L615.68 448.512v126.976l192.96 192.896-40.256 40.256L575.488 615.68H448.512l-192.896 192.96-40.256-40.256L408.32 575.552V448.448L215.36 255.616l40.256-40.256L448.448 408.32h127.104l192.832-192.896z" p-id="22185" fill="#ffffff"></path></svg>
</span>
<div class="progress">
<span :style="{width:'55%'}"></span>
<div class="text">55%</div>
</div>
</div>
<div class="data-infor">
<svg t="1751448794644" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2439" width="16" height="16"><path d="M859.9104 609.92512l0 45.6c-0.67968 2.21952-1.5104 4.4352-1.9648 6.70464-4.66048 24.09984-7.28448 48.82944-14.31552 72.22016-20.84992 69.02016-59.92064 126.53952-114.6944 173.50016-42.24512 36.2496-89.7856 62.36544-144.1344 75.22048-17.87008 4.23552-36.19456 6.73024-54.32064 10.0352l-45.5744 0c-2.21952-0.6848-4.49024-1.72032-6.75456-1.87008-48.12544-2.9952-93.72544-15.52512-136.50048-37.38496-80.86528-41.18528-139.19488-102.5152-165.83552-190.74048-5.67424-18.8544-8.03968-38.62016-11.9744-57.97504l0-43.50976c1.7152-10.69056 3.2-21.47456 5.21984-32.16 8.61952-46.68544 29.36576-88.0256 56.83968-126.19008 25.91488-35.92064 53.44-70.70464 78.016-107.53536 26.56896-39.95008 39.424-84.2944 31.88992-132.9152-1.4848-9.60512-2.87488-19.20896-4.33536-28.76416 0.98048-0.25088 1.9648-0.45056 2.9504-0.73088 59.31008 62.16064 68.96512 138.46528 60.49408 220.92032 2.17088-2.31936 3.98592-3.93472 5.37088-5.79968 50.33984-68.08448 71.96416-143.29984 55.55456-227.54688-10.42944-53.58976-32.99456-101.76512-70.32448-141.81504C369.3056 61.84576 349.69472 47.65568 331.61984 32l18.65472 0c1.536 0.62976 2.976 1.7152 4.53504 1.86496 32.82048 2.81984 63.65056 12.95488 93.02016 27.2 67.17056 32.51584 121.62048 80.58496 167.17056 139.22048 66.9504 86.27968 110.48448 181.99424 119.10528 292.19968 3.30496 42.06976-0.9856 82.95552-12.19968 123.2896-4.23552 15.27552-10.21056 30.04544-15.68 45.94944 21.72544-9.25056 38.24-23.38944 50.9952-41.7152 38.04032-54.77504 48.67456-115.85536 40.05504-183.38048 2.80064 3.24992 4.23552 4.53504 5.21472 6.14528 22.91456 36.19968 40.05504 74.81472 49.0048 116.78464C855.05024 576.17024 857.11488 593.1648 859.9104 609.92512M501.56544 529.61536c-0.85504 0.60544-1.79072 1.2352-2.67008 1.84064-1.18528 16.64-2.06976 33.30048-3.68 49.93536-2.37056 25.38496-8.44544 49.85984-20.32 72.62464-14.52032 27.87968-38.7904 45.21984-65.69088 59.01056-29.00992 14.9696-47.28448 36.34944-49.65504 70.10048-2.46912 34.70976 7.96544 63.86944 35.94496 85.20064 26.21568 19.96032 56.84096 26.4704 89.3056 25.38496 51.82976-1.6896 90.4448-26.32064 105.92512-78.1952 11.11552-37.23008 9.30048-74.71488 1.86496-112.19456-10.16064-51.37536-28.76544-99.26528-60.60032-141.2352C523.04512 550.36032 511.7504 540.40448 501.56544 529.61536" fill="#de833f" p-id="2440"></path></svg>
<div class="infor-right">按照导航路径移动至目标点</div>
</div>
<div class="data-infor">
<svg t="1751448901466" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5172" width="16" height="16"><path d="M169.6 222.6c0-41.2 33.4-74.7 74.7-74.7H294c0.1 0 0.1 0 0.1-0.1V98.3c0-0.1 0-0.1-0.1-0.1h-49.6c-68.8 0-124.6 55.8-124.6 124.6v49.6c0 0.1 0 0.1 0.1 0.1h49.6c0.1 0 0.1 0 0.1-0.1v-49.8zM791.8 98.2h-49.6c-0.1 0-0.1 0-0.1 0.1v49.6c0 0.1 0 0.1 0.1 0.1h49.7c41.2 0 74.7 33.4 74.7 74.7v49.7c0 0.1 0 0.1 0.1 0.1h49.6c0.1 0 0.1 0 0.1-0.1v-49.6c0-68.9-55.8-124.6-124.6-124.6z m74.8 398.2c0-192.5-156-348.5-348.5-348.5S169.6 304 169.6 496.4c0 132 73.4 246.7 181.5 305.9 0.1 0 0.1 0.1 0 0.2l-81.8 92.1c-0.1 0.1 0 0.2 0.1 0.2h74.5l66.8-66.8h0.1c33.8 11 69.9 17 107.4 17s73.5-6.1 107.4-17h0.1l66.8 66.8H767c0.1 0 0.1-0.1 0.1-0.2l-81.8-92.1v-0.2c107.9-59.1 181.3-173.9 181.3-305.9z m-348.4 24.9c-13.8 0-25-11.2-25-25V298c0-14.7 12.1-26.6 26.7-25.5 12.9 0.9 23 11.7 23 24.8v174.2c0 0.1 0 0.1 0.1 0.1h148.6c14.7 0 26.6 12.1 25.5 26.7-0.9 12.9-11.7 23-24.8 23H518.2z" p-id="5173" fill="#edd268"></path></svg>
<div class="infor-right">17 23:00:00 -01 23:00:00</div>
</div>
<div class="data-infor">
<svg t="1751448953457" class="icon" viewBox="0 0 1820 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6479" width="24" height="16"><path d="M383.620741 810.951111c-48.734815 0-88.177778 39.537778-88.177778 88.272593 0 48.734815 39.537778 88.272593 88.177778 88.272592 48.734815 0 88.272593-39.537778 88.272592-88.272592 0-48.734815-39.537778-88.272593-88.272592-88.272593z m288.521481 0c-48.734815 0-88.272593 39.537778-88.272592 88.272593 0 48.734815 39.537778 88.272593 88.272592 88.272592 48.734815 0 88.177778-39.537778 88.177778-88.272592 0-48.734815-39.442963-88.272593-88.177778-88.272593z m462.317037-4.077037c0-5.973333-2.37037-11.757037-6.637037-15.928889-4.266667-4.266667-31.383704-24.082963-37.451852-24.082963h-132.361481V60.681481c0-5.973333-20.574815-33.28-24.841482-37.546666s-10.05037-6.637037-16.118518-6.637037h-68.266667c-6.068148 0-11.851852 2.37037-16.118518 6.637037s-6.637037 9.955556-6.637037 15.928889l-0.474074 639.431111h-21.333334v-44.088889c0-15.928889-32.237037-33.46963-44.088889-44.088889l-94.056296-96.142222c-10.42963-9.481481-24.177778-36.219259-38.305185-36.219259l-44.088889-308.906667c-3.034074-28.728889-14.980741-44.088889-44.088889-44.088889h-243.674074c-31.383704 0-44.088889 12.98963-44.088889 44.088889V457.955556c-31.383704 0-88.272593 57.078519-88.272592 88.272592v308.906667c0 31.194074 12.705185 44.088889 44.088888 44.088889h44.088889c0-71.68 60.112593-132.361481 132.361482-132.361482 72.248889 0 132.361481 60.681481 132.361481 132.361482h22.850371c0-71.68 60.112593-132.361481 132.361481-132.361482 72.248889 0 132.361481 60.681481 132.361482 132.361482h286.34074c6.068148 0 33.185185-4.456296 37.451852-8.628148 4.266667-4.266667 6.637037-29.487407 6.637037-35.460741V806.874074zM489.14963 483.365926c-4.077037 4.551111-9.955556 7.205926-16.023704 7.205926l-21.997037 11.472592V546.133333c0 8.722963 0.474074 44.088889 0 44.088889h-44.088889l-34.133333-0.568889c-8.628148 0-16.971852-3.508148-23.04-9.671111-6.068148-6.162963-9.576296-14.601481-9.576297-23.419259V226.038519c0-18.299259 14.601481-33.09037 32.616297-33.090371h67.128889c16.877037 0 30.90963 12.98963 32.426666 30.056296L494.743704 466.488889c0.568889 6.162963-1.422222 12.325926-5.594074 16.877037z m-38.115556 17.825185c-0.094815-0.18963-0.284444-0.094815-0.474074 0.18963-0.284444 0.18963-0.379259 0.379259-0.18963 0.474074-0.18963 0.568889-0.094815 1.042963 0.853334 0.094815 0.853333-0.853333 0.379259-0.948148-0.18963-0.758519z" p-id="6480" fill="#ffffff"></path></svg>
<svg t="1751448953457" class="icon" viewBox="0 0 1820 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6479" width="24" height="16">
<path
d="M383.620741 810.951111c-48.734815 0-88.177778 39.537778-88.177778 88.272593 0 48.734815 39.537778 88.272593 88.177778 88.272592 48.734815 0 88.272593-39.537778 88.272592-88.272592 0-48.734815-39.537778-88.272593-88.272592-88.272593z m288.521481 0c-48.734815 0-88.272593 39.537778-88.272592 88.272593 0 48.734815 39.537778 88.272593 88.272592 88.272592 48.734815 0 88.177778-39.537778 88.177778-88.272592 0-48.734815-39.442963-88.272593-88.177778-88.272593z m462.317037-4.077037c0-5.973333-2.37037-11.757037-6.637037-15.928889-4.266667-4.266667-31.383704-24.082963-37.451852-24.082963h-132.361481V60.681481c0-5.973333-20.574815-33.28-24.841482-37.546666s-10.05037-6.637037-16.118518-6.637037h-68.266667c-6.068148 0-11.851852 2.37037-16.118518 6.637037s-6.637037 9.955556-6.637037 15.928889l-0.474074 639.431111h-21.333334v-44.088889c0-15.928889-32.237037-33.46963-44.088889-44.088889l-94.056296-96.142222c-10.42963-9.481481-24.177778-36.219259-38.305185-36.219259l-44.088889-308.906667c-3.034074-28.728889-14.980741-44.088889-44.088889-44.088889h-243.674074c-31.383704 0-44.088889 12.98963-44.088889 44.088889V457.955556c-31.383704 0-88.272593 57.078519-88.272592 88.272592v308.906667c0 31.194074 12.705185 44.088889 44.088888 44.088889h44.088889c0-71.68 60.112593-132.361481 132.361482-132.361482 72.248889 0 132.361481 60.681481 132.361481 132.361482h22.850371c0-71.68 60.112593-132.361481 132.361481-132.361482 72.248889 0 132.361481 60.681481 132.361482 132.361482h286.34074c6.068148 0 33.185185-4.456296 37.451852-8.628148 4.266667-4.266667 6.637037-29.487407 6.637037-35.460741V806.874074zM489.14963 483.365926c-4.077037 4.551111-9.955556 7.205926-16.023704 7.205926l-21.997037 11.472592V546.133333c0 8.722963 0.474074 44.088889 0 44.088889h-44.088889l-34.133333-0.568889c-8.628148 0-16.971852-3.508148-23.04-9.671111-6.068148-6.162963-9.576296-14.601481-9.576297-23.419259V226.038519c0-18.299259 14.601481-33.09037 32.616297-33.090371h67.128889c16.877037 0 30.90963 12.98963 32.426666 30.056296L494.743704 466.488889c0.568889 6.162963-1.422222 12.325926-5.594074 16.877037z m-38.115556 17.825185c-0.094815-0.18963-0.284444-0.094815-0.474074 0.18963-0.284444 0.18963-0.379259 0.379259-0.18963 0.474074-0.18963 0.568889-0.094815 1.042963 0.853334 0.094815 0.853333-0.853333 0.379259-0.948148-0.18963-0.758519z"
p-id="6480" fill="#ffffff"></path>
</svg>
<div class="infor-right">
<span class="blue name">Agv-5 </span>当前目标点 <span class="blue">412</span></div>
</div>
</div>
</div>
</div>
</div>
<div class="item">
<div class="content">
<div class="row">
<div class="row-icon">
<component :is="renderIcon('antd DeploymentUnitOutlined')"></component>
</div>
<div class="row-content">
<div class="data-infor">
<svg t="1751447150651" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7400" width="16" height="16"><path d="M426.666667 85.333333a42.666667 42.666667 0 0 1 42.666666 42.666667v298.666667a42.666667 42.666667 0 0 1-42.666666 42.666666H128a42.666667 42.666667 0 0 1-42.666667-42.666666V128a42.666667 42.666667 0 0 1 42.666667-42.666667h298.666667z m42.666666 512a42.666667 42.666667 0 0 0-42.666666-42.666666H128a42.666667 42.666667 0 0 0-42.666667 42.666666v298.666667a42.666667 42.666667 0 0 0 42.666667 42.666667h298.666667a42.666667 42.666667 0 0 0 42.666666-42.666667v-298.666667z m469.333334 0a42.666667 42.666667 0 0 0-42.666667-42.666666h-298.666667a42.666667 42.666667 0 0 0-42.666666 42.666666v298.666667a42.666667 42.666667 0 0 0 42.666666 42.666667h298.666667a42.666667 42.666667 0 0 0 42.666667-42.666667v-298.666667zM384 640H170.666667v213.333333h213.333333v-213.333333z m256 0h213.333333v213.333333h-213.333333v-213.333333z m298.666667-512a42.666667 42.666667 0 0 0-42.666667-42.666667h-298.666667a42.666667 42.666667 0 0 0-42.666666 42.666667v298.666667a42.666667 42.666667 0 0 0 42.666666 42.666666h298.666667a42.666667 42.666667 0 0 0 42.666667-42.666666V128zM384 170.666667H170.666667v213.333333h213.333333V170.666667z m256 0h213.333333v213.333333h-213.333333V170.666667z" fill="#ffffff" p-id="7401"></path></svg>
<span class="green">[运行]</span>
<span>导航到
<svg t="1751450118989" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="22184" width="15" height="15"><path d="M926.784 97.216v829.568H97.216V97.216h829.568z m-56.896 56.832H154.048v715.84h715.84V154.048z m-101.504 61.312l40.256 40.256L615.68 448.512v126.976l192.96 192.896-40.256 40.256L575.488 615.68H448.512l-192.896 192.96-40.256-40.256L408.32 575.552V448.448L215.36 255.616l40.256-40.256L448.448 408.32h127.104l192.832-192.896z" p-id="22185" fill="#ffffff"></path></svg>
</span>
<div class="progress">
<span :style="{width:'55%'}"></span>
<div class="text">55%</div>
</div>
</div>
<div class="data-infor">
<svg t="1751448794644" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2439" width="16" height="16"><path d="M859.9104 609.92512l0 45.6c-0.67968 2.21952-1.5104 4.4352-1.9648 6.70464-4.66048 24.09984-7.28448 48.82944-14.31552 72.22016-20.84992 69.02016-59.92064 126.53952-114.6944 173.50016-42.24512 36.2496-89.7856 62.36544-144.1344 75.22048-17.87008 4.23552-36.19456 6.73024-54.32064 10.0352l-45.5744 0c-2.21952-0.6848-4.49024-1.72032-6.75456-1.87008-48.12544-2.9952-93.72544-15.52512-136.50048-37.38496-80.86528-41.18528-139.19488-102.5152-165.83552-190.74048-5.67424-18.8544-8.03968-38.62016-11.9744-57.97504l0-43.50976c1.7152-10.69056 3.2-21.47456 5.21984-32.16 8.61952-46.68544 29.36576-88.0256 56.83968-126.19008 25.91488-35.92064 53.44-70.70464 78.016-107.53536 26.56896-39.95008 39.424-84.2944 31.88992-132.9152-1.4848-9.60512-2.87488-19.20896-4.33536-28.76416 0.98048-0.25088 1.9648-0.45056 2.9504-0.73088 59.31008 62.16064 68.96512 138.46528 60.49408 220.92032 2.17088-2.31936 3.98592-3.93472 5.37088-5.79968 50.33984-68.08448 71.96416-143.29984 55.55456-227.54688-10.42944-53.58976-32.99456-101.76512-70.32448-141.81504C369.3056 61.84576 349.69472 47.65568 331.61984 32l18.65472 0c1.536 0.62976 2.976 1.7152 4.53504 1.86496 32.82048 2.81984 63.65056 12.95488 93.02016 27.2 67.17056 32.51584 121.62048 80.58496 167.17056 139.22048 66.9504 86.27968 110.48448 181.99424 119.10528 292.19968 3.30496 42.06976-0.9856 82.95552-12.19968 123.2896-4.23552 15.27552-10.21056 30.04544-15.68 45.94944 21.72544-9.25056 38.24-23.38944 50.9952-41.7152 38.04032-54.77504 48.67456-115.85536 40.05504-183.38048 2.80064 3.24992 4.23552 4.53504 5.21472 6.14528 22.91456 36.19968 40.05504 74.81472 49.0048 116.78464C855.05024 576.17024 857.11488 593.1648 859.9104 609.92512M501.56544 529.61536c-0.85504 0.60544-1.79072 1.2352-2.67008 1.84064-1.18528 16.64-2.06976 33.30048-3.68 49.93536-2.37056 25.38496-8.44544 49.85984-20.32 72.62464-14.52032 27.87968-38.7904 45.21984-65.69088 59.01056-29.00992 14.9696-47.28448 36.34944-49.65504 70.10048-2.46912 34.70976 7.96544 63.86944 35.94496 85.20064 26.21568 19.96032 56.84096 26.4704 89.3056 25.38496 51.82976-1.6896 90.4448-26.32064 105.92512-78.1952 11.11552-37.23008 9.30048-74.71488 1.86496-112.19456-10.16064-51.37536-28.76544-99.26528-60.60032-141.2352C523.04512 550.36032 511.7504 540.40448 501.56544 529.61536" fill="#de833f" p-id="2440"></path></svg>
<div class="infor-right">按照导航路径移动至目标点</div>
</div>
<div class="data-infor">
<svg t="1751448901466" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5172" width="16" height="16"><path d="M169.6 222.6c0-41.2 33.4-74.7 74.7-74.7H294c0.1 0 0.1 0 0.1-0.1V98.3c0-0.1 0-0.1-0.1-0.1h-49.6c-68.8 0-124.6 55.8-124.6 124.6v49.6c0 0.1 0 0.1 0.1 0.1h49.6c0.1 0 0.1 0 0.1-0.1v-49.8zM791.8 98.2h-49.6c-0.1 0-0.1 0-0.1 0.1v49.6c0 0.1 0 0.1 0.1 0.1h49.7c41.2 0 74.7 33.4 74.7 74.7v49.7c0 0.1 0 0.1 0.1 0.1h49.6c0.1 0 0.1 0 0.1-0.1v-49.6c0-68.9-55.8-124.6-124.6-124.6z m74.8 398.2c0-192.5-156-348.5-348.5-348.5S169.6 304 169.6 496.4c0 132 73.4 246.7 181.5 305.9 0.1 0 0.1 0.1 0 0.2l-81.8 92.1c-0.1 0.1 0 0.2 0.1 0.2h74.5l66.8-66.8h0.1c33.8 11 69.9 17 107.4 17s73.5-6.1 107.4-17h0.1l66.8 66.8H767c0.1 0 0.1-0.1 0.1-0.2l-81.8-92.1v-0.2c107.9-59.1 181.3-173.9 181.3-305.9z m-348.4 24.9c-13.8 0-25-11.2-25-25V298c0-14.7 12.1-26.6 26.7-25.5 12.9 0.9 23 11.7 23 24.8v174.2c0 0.1 0 0.1 0.1 0.1h148.6c14.7 0 26.6 12.1 25.5 26.7-0.9 12.9-11.7 23-24.8 23H518.2z" p-id="5173" fill="#edd268"></path></svg>
<div class="infor-right">17 23:00:00 -01 23:00:00</div>
</div>
<div class="data-infor">
<svg t="1751448953457" class="icon" viewBox="0 0 1820 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6479" width="24" height="16"><path d="M383.620741 810.951111c-48.734815 0-88.177778 39.537778-88.177778 88.272593 0 48.734815 39.537778 88.272593 88.177778 88.272592 48.734815 0 88.272593-39.537778 88.272592-88.272592 0-48.734815-39.537778-88.272593-88.272592-88.272593z m288.521481 0c-48.734815 0-88.272593 39.537778-88.272592 88.272593 0 48.734815 39.537778 88.272593 88.272592 88.272592 48.734815 0 88.177778-39.537778 88.177778-88.272592 0-48.734815-39.442963-88.272593-88.177778-88.272593z m462.317037-4.077037c0-5.973333-2.37037-11.757037-6.637037-15.928889-4.266667-4.266667-31.383704-24.082963-37.451852-24.082963h-132.361481V60.681481c0-5.973333-20.574815-33.28-24.841482-37.546666s-10.05037-6.637037-16.118518-6.637037h-68.266667c-6.068148 0-11.851852 2.37037-16.118518 6.637037s-6.637037 9.955556-6.637037 15.928889l-0.474074 639.431111h-21.333334v-44.088889c0-15.928889-32.237037-33.46963-44.088889-44.088889l-94.056296-96.142222c-10.42963-9.481481-24.177778-36.219259-38.305185-36.219259l-44.088889-308.906667c-3.034074-28.728889-14.980741-44.088889-44.088889-44.088889h-243.674074c-31.383704 0-44.088889 12.98963-44.088889 44.088889V457.955556c-31.383704 0-88.272593 57.078519-88.272592 88.272592v308.906667c0 31.194074 12.705185 44.088889 44.088888 44.088889h44.088889c0-71.68 60.112593-132.361481 132.361482-132.361482 72.248889 0 132.361481 60.681481 132.361481 132.361482h22.850371c0-71.68 60.112593-132.361481 132.361481-132.361482 72.248889 0 132.361481 60.681481 132.361482 132.361482h286.34074c6.068148 0 33.185185-4.456296 37.451852-8.628148 4.266667-4.266667 6.637037-29.487407 6.637037-35.460741V806.874074zM489.14963 483.365926c-4.077037 4.551111-9.955556 7.205926-16.023704 7.205926l-21.997037 11.472592V546.133333c0 8.722963 0.474074 44.088889 0 44.088889h-44.088889l-34.133333-0.568889c-8.628148 0-16.971852-3.508148-23.04-9.671111-6.068148-6.162963-9.576296-14.601481-9.576297-23.419259V226.038519c0-18.299259 14.601481-33.09037 32.616297-33.090371h67.128889c16.877037 0 30.90963 12.98963 32.426666 30.056296L494.743704 466.488889c0.568889 6.162963-1.422222 12.325926-5.594074 16.877037z m-38.115556 17.825185c-0.094815-0.18963-0.284444-0.094815-0.474074 0.18963-0.284444 0.18963-0.379259 0.379259-0.18963 0.474074-0.18963 0.568889-0.094815 1.042963 0.853334 0.094815 0.853333-0.853333 0.379259-0.948148-0.18963-0.758519z" p-id="6480" fill="#ffffff"></path></svg>
<div class="infor-right">
<span class="blue name">Agv-5 </span>当前目标点 <span class="blue">412</span></div>
<span class="blue name">{{ deviceInfo.id }} </span>当前姿态 <span class="blue">{{ deviceInfo.logicX + '_' + deviceInfo.logicY + '(' + deviceInfo.direction + ')' }}</span></div>
</div>
</div>
</div>
@ -141,107 +96,336 @@
</template>
<script>
import IWidgets from '../IWidgets.js'
import { worldModel } from '@/core/manager/WorldModel.js'
export default {
name: 'MonitorView',
webSocketSubscribe: ['deviceStatus'],
mixins: [IWidgets],
data() {
return {
searchKeyword: '',
selectedId: '',
/*
设备列表, 数据展示为:
[
{
id: 'device-id',
type: 'device-type',
online: true,
x: 0,
y: 0,
z: 0,
logicX: 0,
logicY: 0,
direction: 'up',
orientation: 0,
soc: 100,
mode: 'AMR_FREE_MODE',
taskStatus: 'IDLE',
isBlocked: false,
taskCompleted: 0,
taskTotalCount: 10
}
]
*/
/**
* 设备列表数据
* @type {Array<{
id: string,
type: string,
online: boolean,
x: number,
y: number,
z: number,
logicX: number,
logicY: number,
direction: string,
orientation: number,
soc: number,
mode: 'AMR_FREE_MODE' |
'AMR_INIT_MODE' |
'AMR_TASK_MODE' |
'AMR_SINGLE_ACTION_MODE' |
'AMR_MANUAL_MODE' |
'AMR_HANDSET_MODE' |
'AMR_CHARGE_MODE' |
'AMR_TASK_INTERRUPT_MODE' |
'AMR_CUSTOMIZE_MODE',
taskStatus: string,
isBlocked: boolean,
taskCompleted: number,
taskTotalCount: number
// ID
bizTaskId: string
// : / / / /
bizTaskType: '' | 'MOVE' |'CHARGE' |'CARRY' |'LOAD' |'UNLOAD'
// WAY_1_1 Rack1/0/0/0
bizTaskFrom: string
// WAY_1_1 Rack1/0/0/0 charge1
bizTaskTo: string
}>}
*/
deviceList: []
}
},
methods: {
/**
* 处理设备存活消息
* @type {(type: BackendTopicType, topic: string, body: {
* id: string
* type: string
* online: boolean
* }) => void}
*/
onDeviceAliveMessage: (type, topic, body) => {
console.log(this, topic, body)
debugger
let deviceInfo = _.find(this.deviceList, device => device.id === body.id)
if (!deviceInfo) {
//
deviceInfo = {
id: body.id,
type: body.type,
online: body.online
}
this.deviceList.push(deviceInfo)
}
},
/**
* 处理设备存活消息
* @type {DeviceStatusFn}
*/
onDeviceStatusMessage: (type, topic, body) => {
console.log(this, topic, body)
debugger
const deviceInfo = _.find(this.deviceList, device => device.id === body.id)
if (!deviceInfo) {
return
}
_.assign(deviceInfo, body)
console.log(this, topic, body)
},
async subscribe() {
this.deviceList = []
const list = await LCC.loadExecutor()
this.deviceList = _.map(list, executorVo => {
const row = {
online: false
}
return {
id: executorVo.executor_id,
type: row.type,
online: row.online,
x: row.x,
y: row.y,
z: row.z,
logicX: row.logicX,
logicY: row.logicY,
direction: row.direction,
orientation: row.orientation,
soc: row.soc,
mode: row.mode,
taskStatus: row.taskStatus,
isBlocked: row.isBlocked,
taskCompleted: row.taskCompleted || 0,
taskTotalCount: row.taskTotalCount || 0,
bizTaskId: row.bizTaskId || '',
bizTaskType: row.bizTaskType || '',
bizTaskFrom: row.bizTaskFrom || '',
bizTaskTo: row.bizTaskTo || ''
}
})
//
LCC.subscribe('DeviceAlive', this.onDeviceAliveMessage)
LCC.subscribe('DeviceStatus', this.onDeviceStatusMessage)
},
undescribe() {
//
LCC.unsubscribe('DeviceAlive', this.onDeviceAliveMessage)
LCC.unsubscribe('DeviceStatus', this.onDeviceStatusMessage)
},
getDeviceModeDesc(deviceInfo) {
switch (deviceInfo.mode) {
case 'AMR_FREE_MODE':
return '空闲模式'
case 'AMR_INIT_MODE':
return '初始化模式'
case 'AMR_TASK_MODE':
return '任务模式'
case 'AMR_SINGLE_ACTION_MODE':
return '单动作模式'
case 'AMR_MANUAL_MODE':
return '手动模式'
case 'AMR_HANDSET_MODE':
return '遥控器模式'
case 'AMR_CHARGE_MODE':
return '充电模式'
case 'AMR_TASK_INTERRUPT_MODE':
return '任务被中断模式'
case 'AMR_CUSTOMIZE_MODE':
return '自定义模式'
default:
return deviceInfo.mode
}
},
getDeviceTaskTypeDesc(deviceInfo) {
switch (deviceInfo.bizTaskType) {
case 'MOVE':
return '移动任务'
case 'CHARGE':
return '充电任务'
case 'CARRY':
return '搬运任务'
case 'LOAD':
return '装载任务'
case 'UNLOAD':
return '卸载任务'
default:
return ''
}
}
},
computed: {
/*
total: 0,
online: 0,
offline: 0,
running: 0,
idle: 0
idle: 0,
*/
total() {
return this.deviceList.length
},
online() {
return this.deviceList.filter(device => device.online).length
},
offline() {
return this.deviceList.filter(device => !device.online).length
},
running() {
return this.deviceList.filter(device => device.taskStatus === 'EXECUTING').length
},
idle() {
return this.deviceList.filter(device => device.taskStatus === 'IDLE').length
}
},
watch: {
errorDescription: {
handler(newVal) {
if (newVal) {
this.undescribe()
} else {
this.subscribe()
}
},
methods: {}
immediate: true
}
}
}
</script>
<style lang="less">
.monitor-tool-wrap{
.monitor-tool-wrap {
width: 100%;
height: 100%;
overflow: hidden;
display: flex;
flex-direction: column;
.infor-row{
.infor-row {
display: flex;
flex-direction: row;
flex-wrap: wrap;
//background: #cdcccc;
padding:3px 0;
.infor-item{
margin:2px 8px;
padding: 3px 0;
.infor-item {
margin: 2px 8px;
font-size: 12px;
background: #f3e9c0;
border-radius: 3px;
padding: 0 5px;
}
.num{
.num {
display: inline-block;
padding:0 3px;
padding: 0 3px;
font-weight: bold;
color: #333;
&:first-child{
&:first-child {
margin-left: 0;
}
&:last-child{
&:last-child {
margin-right: 0;
}
&.num-red{
&.num-red {
color: red;
}
&.num-green{
&.num-green {
color: green;
}
&.num-blue{
&.num-blue {
color: blue;
}
&.num-orange{
&.num-orange {
color: #d78f0b;
}
}
}
.list{
flex:1;
.list {
flex: 1;
overflow: auto;
font-size: 12px;
color:#fff;
.item{
color: #fff;
.item {
display: flex;
flex-direction: column;
border:2px solid #808080;
margin:5px 5px;
border: 2px solid #808080;
margin: 5px 5px;
border-radius: 5px;
background: #747a80;
&.selected{
&.selected {
border-color: #fa9d12;
}
.title{
.title {
display: flex;
align-items: center;
padding:3px 10px;
padding: 3px 10px;
border-bottom: 1px solid #81888e;
margin-bottom: 5px;
.num{
.num {
font-weight: bold;
margin-left:5px;
margin-left: 5px;
}
.el-icon{
.el-icon {
margin: 0 5px;
font-size: 15px;
}
}
.content{
flex:1;
.content {
flex: 1;
padding: 5px 0;
.row{
.row {
display: flex;
flex-direction: row;
margin:0 5px;
.row-icon{
margin: 0 5px;
.row-icon {
width: 75px;
height: 75px;
background: #3e454c;
@ -249,52 +433,63 @@ export default {
display: flex;
justify-content: center;
align-items: center;
.el-icon{
.el-icon {
font-size: 70px;
color: #fff;
}
}
.row-content{
flex:1;
margin-left:5px;
.row-content {
flex: 1;
margin-left: 5px;
}
}
.data-infor{
margin:3px 0;
.data-infor {
margin: 3px 0;
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
.infor-right{
flex:1;
.infor-right {
flex: 1;
flex-shrink: 0;
span{
&.blue{
span {
&.blue {
color: #3dc4ff;
}
&.name{
margin-right:15px;
&.name {
margin-right: 15px;
}
}
}
&>span{
margin-right:3px;
&.green{
color:#00ff00;
& > span {
margin-right: 3px;
&.green {
color: #00ff00;
}
&>svg{
& > svg {
position: relative;
top:3px;
top: 3px;
}
}
.progress{
flex:1;
min-width:80px;
border:1px solid #dcdcdc;
.progress {
flex: 1;
min-width: 80px;
border: 1px solid #dcdcdc;
height: 20px;
margin-left:5px;
margin-left: 5px;
position: relative;
span{
span {
font-size: 12px;
background: #7ac678;
display: inline-block;
@ -302,19 +497,21 @@ export default {
text-align: center;
height: 18px;
}
.text{
.text {
position: absolute;
width: 100%;
height:100%;
left:0;
top:0;
height: 100%;
left: 0;
top: 0;
text-align: center;
}
}
&>svg{
& > svg {
margin-right: 5px;
position: relative;
top:1px;
top: 1px;
}
}
}

1
src/editor/widgets/task/TaskView.vue

@ -94,7 +94,6 @@ import IWidgets from '../IWidgets.js'
export default {
name: 'TaskView',
webSocketSubscribe: ['task'],
mixins: [IWidgets],
data() {
return {

92
src/types/LCC.d.ts

@ -25,15 +25,105 @@ declare interface LCC {
/**
* Model
*/
loadExecutor(): Promise<ServerResponse<ExecutorVo>>
loadExecutor(): Promise<ExecutorVo>
/**
*
* @param scriptList
*/
saveAndSyncScripts(scriptList: { name: string, content: string }[]): Promise<ServerResponse<{ name: string, content: string }[]>>
/**
*
* @param topicType
* @param eventHandler
*/
subscribe(topicType: BackendTopicType, eventHandler: BackendMessageHandler);
/**
*
* @param topicType
* @param eventHandler
*/
unsubscribe(topicType: BackendTopicType, eventHandler: BackendMessageHandler);
}
/**
*
*/
type BackendTopicType = 'ServerState' | 'ClientState' | 'TaskUpdate' | 'InvUpdate' |
'DeviceStatus' | 'DeviceAlive' | 'Logs' | 'Alarm' | 'ScriptUpdate'
type DeviceAliveFn = (type: BackendTopicType, topic: string, body: {
id: string
type: string
online: boolean
}) => void
type DeviceStatusFn = (type: BackendTopicType, topic: string, body: {
// 设备 ID
id: string
// 设备类型
type: string
// 设备x,y,z坐标
x: number
y: number
z: number
// 设备逻辑坐标x,y
logicX: number
logicY: number
// 设备姿态(up/down/left/right)
direction: string
// 设备旋转角度
orientation: number
// 电池电量
soc: number
// 工作模式:
// AMR_FREE_MODE=空闲模式;
// AMR_INIT_MODE=初始化模式;
// AMR_TASK_MODE=任务模式;
// AMR_SINGLE_ACTION_MODE=单动作模式;
// AMR_MANUAL_MODE=手动模式;
// AMR_HANDSET_MODE=遥控器模式;
// AMR_CHARGE_MODE=充电模式;
// AMR_TASK_INTERRUPT_MODE=任务被中断模式;
// AMR_CUSTOMIZE_MODE=自定义模式;
mode: 'AMR_FREE_MODE' |
'AMR_INIT_MODE' |
'AMR_TASK_MODE' |
'AMR_SINGLE_ACTION_MODE' |
'AMR_MANUAL_MODE' |
'AMR_HANDSET_MODE' |
'AMR_CHARGE_MODE' |
'AMR_TASK_INTERRUPT_MODE' |
'AMR_CUSTOMIZE_MODE'
// 任务状态 ID: IDLE / PAUSED / EXECUTING
taskStatus: string
// 是否阻挡
isBlocked: boolean
// 已完成任务数
taskCompleted: number
// 总共任务数,通过 taskCompleted/taskTotalCount 可以计算出完成率
taskTotalCount: number
// 业务任务ID
bizTaskId: string
// 业务任务类型: 移动任务 / 充电任务 / 搬运任务 / 装载任务 / 卸载任务
bizTaskType: '' | 'MOVE' | 'CHARGE' | 'CARRY' | 'LOAD' | 'UNLOAD'
// 业务任务类型: 待调度 / 设备执行中 / 暂停执行 / 调度异常 / 规划异常 / 设备执行异常
bizTaskStatus: 'WAITING_FOR_DISPATCH' | 'DEVICE_EXECUTING' | 'PAUSED' | 'DISPATCH_ERROR' | 'PLANNING_ERROR' | 'DEVICE_ERROR'
// 比如 WAY_1_1 Rack1/0/0/0
bizTaskFrom: string
// 比如 WAY_1_1 Rack1/0/0/0 charge1
bizTaskTo: string
// 搬运托盘号
bizLpn: string
}) => void
/**
*
*/
type BackendMessageHandler = (type: BackendTopicType, topic: string, message: any) => void
type ContainerT = 'pallet' | 'tote' | 'carton' | 'box'
interface InvVo {

1
src/types/ModelTypes.ts

@ -74,3 +74,4 @@ export const MaterialQualityEnum = {
Low: 2
}

Loading…
Cancel
Save