|
|
@ -1,52 +1,16 @@ |
|
|
|
<template> |
|
|
|
<div class="component-page p-4 text-title"> |
|
|
|
<el-tabs type="border-card"> |
|
|
|
<el-tab-pane label="复合动作"> |
|
|
|
<div class="tabFrame"> |
|
|
|
<div class="frame"> |
|
|
|
<div class="flex items-center gap-4 flex-wrap"> |
|
|
|
<label>加热区编号:</label> |
|
|
|
<el-select v-model="selectedArea" placeholder="Select" style="width: 200px"> |
|
|
|
<el-option |
|
|
|
v-for="item in areaOptions" |
|
|
|
:key="item.value" |
|
|
|
:label="item.label" |
|
|
|
:value="item.value" /> |
|
|
|
</el-select> |
|
|
|
<!-- <label>托盘高度:</label> |
|
|
|
<input type="number" class="rounded-sm px-2" /> |
|
|
|
<span>mm</span> --> |
|
|
|
</div> |
|
|
|
<div class="flex gap-4 flex-wrap"> |
|
|
|
<button class="btn-light px-2 py-1" @click="onCmdClick('takeOffCap')">取下拍子</button> |
|
|
|
<button class="btn-light px-2 py-1" @click="onCmdClick('putBackCap')">装回拍子</button> |
|
|
|
<button class="btn-light px-2 py-1" @click="onCmdClick('moveToActionArea')"> |
|
|
|
移至操作区(加液、摇匀、拍照) |
|
|
|
</button> |
|
|
|
<button class="btn-light px-2 py-1" @click="onCmdClick('moveToHeatArea')"> |
|
|
|
(从操作区)移至加热区 |
|
|
|
</button> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="frame"> |
|
|
|
<div class="flex items-center gap-4"> |
|
|
|
<label>源位置:</label> |
|
|
|
<input type="number" class="rounded-sm px-2" /> |
|
|
|
<label>目标位置:</label> |
|
|
|
<input type="number" class="rounded-sm px-2" /> |
|
|
|
</div> |
|
|
|
<button class="btn-light px-2 py-1 min-w-20" @click="onCmdClick('moveTube')">移动试管</button> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</el-tab-pane> |
|
|
|
<el-tab-pane label="单一动作"> |
|
|
|
<div class="frame"> |
|
|
|
<div class="flex items-center gap-4 flex-wrap"> |
|
|
|
<label>加热区编号:</label> |
|
|
|
<el-select v-model="selectedAreaForHeat" placeholder="Select" style="width: 200px"> |
|
|
|
<el-select v-model="selectedAreaForTray" placeholder="Select" style="width: 200px"> |
|
|
|
<el-option v-for="item in areaOptions" :key="item.value" :label="item.label" :value="item.value" /> |
|
|
|
</el-select> |
|
|
|
<label>升降高度:</label> |
|
|
|
<input type="number" v-model="trayHeight" class="rounded-sm px-2" /> |
|
|
|
<span>mm</span> |
|
|
|
</div> |
|
|
|
<div class="flex gap-4 flex-wrap"> |
|
|
|
<button class="btn-light px-2 py-1" @click="onCmdClick('upTray')">抬起托盘</button> |
|
|
@ -61,7 +25,11 @@ |
|
|
|
class="rounded-sm px-1 w-16" /> |
|
|
|
Z:<input type="number" v-model="z" class="rounded-sm px-1 w-16" /> |
|
|
|
<label for="">当前位置:</label> |
|
|
|
<span class="text-warn">50,50,50</span> |
|
|
|
<span class="text-warn">{{ |
|
|
|
`${statusStore.status?.railArm.x || 0},${statusStore.status?.railArm.y || 0},${ |
|
|
|
statusStore.status?.railArm.z || 0 |
|
|
|
}` |
|
|
|
}}</span> |
|
|
|
</div> |
|
|
|
<button class="btn-light px-2 py-1 min-w-20" @click="onCmdClick('moveMachineArm')">移动机械臂</button> |
|
|
|
</div> |
|
|
@ -78,8 +46,8 @@ |
|
|
|
<label for="">注入量:</label> |
|
|
|
<input type="number" v-model="pumpAmount" class="rounded-sm px-2" placeholder="输入注入量" /> |
|
|
|
<span>ml</span> |
|
|
|
<label for="">当前容量:</label> |
|
|
|
<span class="text-warn">50</span> |
|
|
|
<!-- <label for="">当前容量:</label> |
|
|
|
<span class="text-warn">50</span> --> |
|
|
|
</div> |
|
|
|
<div class="flex gap-4 flex-wrap"> |
|
|
|
<button class="btn-light px-2 py-1" @click="onCmdClick('injectFluid')">注入溶液</button> |
|
|
@ -94,14 +62,16 @@ |
|
|
|
<label>温度:</label> |
|
|
|
<input type="number" v-model="heatTemperature" class="rounded-sm px-2" placeholder="输入温度" /> |
|
|
|
<span>℃</span> |
|
|
|
<label for="">当前温度:</label> |
|
|
|
<span class="text-warn">50</span> |
|
|
|
</div> |
|
|
|
<div class="flex gap-4 flex-wrap"> |
|
|
|
<button class="btn-light px-2 py-1" @click="onCmdClick('startHeat')">开始加热</button> |
|
|
|
<button class="btn-light px-2 py-1" @click="onCmdClick('stopHeat')">停止加热</button> |
|
|
|
<!-- <button class="btn-light px-2 py-1 min-w-20" @click="onCmdClick('keepHeat')">恒温</button> --> |
|
|
|
</div> |
|
|
|
<div> |
|
|
|
<label for="">当前温度:</label> |
|
|
|
<span class="text-warn">{{ (statusStore.status?.heater || []).map(h => h.current).join(",") }}</span> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="frame"> |
|
|
@ -116,6 +86,44 @@ |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</el-tab-pane> |
|
|
|
|
|
|
|
<el-tab-pane label="复合动作"> |
|
|
|
<div class="tabFrame"> |
|
|
|
<div class="frame"> |
|
|
|
<div class="flex items-center gap-4 flex-wrap"> |
|
|
|
<label>加热区编号:</label> |
|
|
|
<el-select v-model="selectedArea" placeholder="Select" style="width: 200px"> |
|
|
|
<el-option |
|
|
|
v-for="item in areaOptions" |
|
|
|
:key="item.value" |
|
|
|
:label="item.label" |
|
|
|
:value="item.value" /> |
|
|
|
</el-select> |
|
|
|
</div> |
|
|
|
<div class="flex gap-4 flex-wrap"> |
|
|
|
<button class="btn-light px-2 py-1" @click="onCmdClick('takeOffCap')">取下拍子</button> |
|
|
|
<button class="btn-light px-2 py-1" @click="onCmdClick('putBackCap')">装回拍子</button> |
|
|
|
<button class="btn-light px-2 py-1" @click="onCmdClick('moveToActionArea')"> |
|
|
|
移至操作区(加液、摇匀、拍照) |
|
|
|
</button> |
|
|
|
<button class="btn-light px-2 py-1" @click="onCmdClick('moveToHeatArea')"> |
|
|
|
(从操作区)移至加热区 |
|
|
|
</button> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="frame"> |
|
|
|
<div class="flex items-center gap-4"> |
|
|
|
<label>源位置:</label> |
|
|
|
<input type="number" class="rounded-sm px-2" /> |
|
|
|
<label>目标位置:</label> |
|
|
|
<input type="number" class="rounded-sm px-2" /> |
|
|
|
</div> |
|
|
|
<button class="btn-light px-2 py-1 min-w-20" @click="onCmdClick('moveTube')">移动试管</button> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</el-tab-pane> |
|
|
|
|
|
|
|
<el-tab-pane label="校准"> |
|
|
|
<h1 class="text-lg font-medium py-2">加热区坐标:</h1> |
|
|
|
<div |
|
|
@ -167,12 +175,18 @@ import { updateConfig } from "@/services/sysConfig/sysConfig"; |
|
|
|
import { useSettingStore } from "@/stores/setting"; |
|
|
|
import { showToast } from "vant"; |
|
|
|
import { computed, onMounted, onUnmounted, ref } from "vue"; |
|
|
|
import { ElMessage } from "element-plus"; |
|
|
|
import { useStatusStore } from "@/stores/status"; |
|
|
|
import { getTxnRecord } from "@/services/txn"; |
|
|
|
|
|
|
|
const settingStore = useSettingStore(); |
|
|
|
const statusStore = useStatusStore(); |
|
|
|
|
|
|
|
const selectedArea = ref(""); |
|
|
|
const selectedAreaForHeat = ref(""); |
|
|
|
const selectedArea = ref(2); |
|
|
|
const selectedAreaForTray = ref(2); |
|
|
|
const selectedAreaForHeat = ref(2); |
|
|
|
const heatTemperature = ref(0); |
|
|
|
const trayHeight = ref(0); |
|
|
|
|
|
|
|
const x = ref(0); |
|
|
|
const y = ref(0); |
|
|
@ -192,9 +206,22 @@ onMounted(() => { |
|
|
|
const subscription = wsClient.dataOb.subscribe(data => { |
|
|
|
console.log(data); |
|
|
|
if (data.type === "cmd") { |
|
|
|
const cmdName = CmdDescMap[data.data.commandName]; |
|
|
|
const result = data.data.status === "D0000" ? "执行完毕" : "执行失败"; |
|
|
|
showToast(`${cmdName} ${result}`); |
|
|
|
const cmdInfo = getTxnRecord(data.data.commandId); |
|
|
|
if (cmdInfo.category === "debug") { |
|
|
|
const cmdName = CmdDescMap[cmdInfo.command]; |
|
|
|
const result = data.data.status === "D0000" ? "执行完毕" : "执行失败"; |
|
|
|
ElMessage({ |
|
|
|
message: `${cmdName} ${result}`, |
|
|
|
type: data.data.status === "D0000" ? "success" : "error", |
|
|
|
}); |
|
|
|
} |
|
|
|
} else if (data.type === "status") { |
|
|
|
statusStore.setStatus(data.data); |
|
|
|
} else if (data.type === "warn") { |
|
|
|
ElMessage({ |
|
|
|
message: data.data.message, |
|
|
|
type: "warning", |
|
|
|
}); |
|
|
|
} |
|
|
|
}); |
|
|
|
wsClient.connect(); |
|
|
@ -205,7 +232,30 @@ onMounted(() => { |
|
|
|
}); |
|
|
|
|
|
|
|
function onCmdClick(command: DebugCmd) { |
|
|
|
debugCmd({ command, params: {} }).then(res => { |
|
|
|
let params: Record<string, any> = {}; |
|
|
|
if (command === "upTray") { |
|
|
|
params = { areaId: selectedAreaForTray.value, height: trayHeight.value }; |
|
|
|
} else if (command === "downTray") { |
|
|
|
params = { areaId: selectedAreaForTray.value, height: trayHeight.value }; |
|
|
|
} else if (command === "moveMachineArm") { |
|
|
|
params = { x: x.value, y: y.value, z: z.value }; |
|
|
|
} else if (command === "injectFluid") { |
|
|
|
params = { areaId: pumpId.value, volume: pumpAmount.value }; |
|
|
|
} else if (command === "startHeat") { |
|
|
|
params = { areaId: selectedAreaForHeat.value, temperature: heatTemperature.value }; |
|
|
|
} else if (command === "stopHeat") { |
|
|
|
params = { areaId: selectedAreaForHeat.value }; |
|
|
|
} else if (command === "startShakeUp") { |
|
|
|
params = { speed: shakeUpSpeed.value }; |
|
|
|
} else if ( |
|
|
|
command === "takeOffCap" || |
|
|
|
command === "putBackCap" || |
|
|
|
command === "moveToActionArea" || |
|
|
|
command === "moveToHeatArea" |
|
|
|
) { |
|
|
|
params = { areaId: selectedArea.value }; |
|
|
|
} |
|
|
|
debugCmd({ command, params }).then(res => { |
|
|
|
if (res.success) { |
|
|
|
// showToast("已执行,请稍等"); |
|
|
|
} else { |
|
|
@ -213,6 +263,7 @@ function onCmdClick(command: DebugCmd) { |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
function saveConfig() { |
|
|
|
const heatCfg = settingStore.heatAreaConfig.map(c => ({ |
|
|
|
id: c.id, |
|
|
@ -233,6 +284,7 @@ function saveConfig() { |
|
|
|
}); |
|
|
|
} |
|
|
|
</script> |
|
|
|
|
|
|
|
<style lang="scss" scoped> |
|
|
|
.tabFrame { |
|
|
|
overflow: auto; |
|
|
|