14 changed files with 516 additions and 34 deletions
-
14public/index.html
-
11public/main.js
-
0src/config/db.ts
-
0src/controllers/cmd.ts
-
56src/index.ts
-
0src/middlewares/auth.ts
-
0src/middlewares/logger.ts
-
0src/models/User.ts
-
20src/routes/cmd.ts
-
23src/routes/debug.ts
-
142src/types/cmdTypes.ts
-
266src/types/wsTypes.ts
-
7src/utils/helper.ts
-
11src/utils/wss.ts
@ -0,0 +1,20 @@ |
|||||
|
import express from "express"; |
||||
|
import { delay } from "../utils/helper"; |
||||
|
import { wsSend } from "../utils/wss"; |
||||
|
const router = express.Router(); |
||||
|
|
||||
|
router.post("/", async (req, res) => { |
||||
|
await delay(200); |
||||
|
setTimeout(() => { |
||||
|
wsSend(req.app.locals["wss"], { |
||||
|
type: "cmd", |
||||
|
data: { |
||||
|
commandId: req.body.commandId, |
||||
|
status: "D0000", |
||||
|
}, |
||||
|
}); |
||||
|
}, 2000); |
||||
|
res.json({ code: "00000", msg: "执行成功" }); |
||||
|
}); |
||||
|
|
||||
|
export default router; |
@ -0,0 +1,23 @@ |
|||||
|
import express from "express"; |
||||
|
import { delay } from "../utils/helper"; |
||||
|
import { wsSend } from "../utils/wss"; |
||||
|
import { StatusDatagram } from "../types/wsTypes"; |
||||
|
const router = express.Router(); |
||||
|
|
||||
|
router.post("/railArm", async (req, res) => { |
||||
|
// await delay(200);
|
||||
|
const curr: StatusDatagram["data"] = req.app.locals["status"]; |
||||
|
setTimeout(() => { |
||||
|
curr.railArm.x = req.body.x; |
||||
|
curr.railArm.y = req.body.y; |
||||
|
curr.railArm.z = req.body.z; |
||||
|
wsSend(req.app.locals["wss"], { |
||||
|
type: "status", |
||||
|
data: curr, |
||||
|
}); |
||||
|
}, 1000); |
||||
|
|
||||
|
res.json({ code: "00000", msg: "执行成功" }); |
||||
|
}); |
||||
|
|
||||
|
export default router; |
@ -0,0 +1,142 @@ |
|||||
|
|
||||
|
type UpTrayStepStruct = { |
||||
|
method: "upTray"; |
||||
|
// params: {
|
||||
|
// heaterId: number;
|
||||
|
// };
|
||||
|
}; |
||||
|
type DownTrayStepStruct = { |
||||
|
method: "downTray"; |
||||
|
// params: {
|
||||
|
// heaterId: number;
|
||||
|
// };
|
||||
|
}; |
||||
|
export type TubeSolStruct = { |
||||
|
tubeNum: number; |
||||
|
addLiquidList: Array<{ |
||||
|
solId: number; |
||||
|
volume: number; |
||||
|
}>; |
||||
|
}; |
||||
|
type AddLiquidStepStruct = { |
||||
|
method: "addLiquid"; |
||||
|
params: { |
||||
|
solId: number; |
||||
|
volume: number; |
||||
|
tubeSolList?: TubeSolStruct[]; |
||||
|
}; |
||||
|
}; |
||||
|
type MoveToSolStepStruct = { |
||||
|
method: "moveToSol"; |
||||
|
// params: {
|
||||
|
// heaterId: number;
|
||||
|
// };
|
||||
|
}; |
||||
|
type MoveToHeaterStepStruct = { |
||||
|
method: "moveToHeat"; |
||||
|
// params: {
|
||||
|
// heaterId: number;
|
||||
|
// };
|
||||
|
}; |
||||
|
type ShakingStepStruct = { |
||||
|
method: "shaking"; |
||||
|
params: { |
||||
|
second: number; |
||||
|
}; |
||||
|
}; |
||||
|
|
||||
|
type StartHeatingStepStruct = { |
||||
|
method: "startHeating"; |
||||
|
params: { |
||||
|
// heaterId: number;
|
||||
|
temperature: number; |
||||
|
}; |
||||
|
}; |
||||
|
type StopHeatingStepStruct = { |
||||
|
method: "stopHeating"; |
||||
|
// params: {
|
||||
|
// heaterId: number;
|
||||
|
// };
|
||||
|
}; |
||||
|
type TakePhotoStepStruct = { |
||||
|
method: "takePhoto"; |
||||
|
}; |
||||
|
type DelayStepStruct = { |
||||
|
method: "delay"; |
||||
|
params: { |
||||
|
second: number; |
||||
|
}; |
||||
|
}; |
||||
|
|
||||
|
export type StepStruct = |
||||
|
| UpTrayStepStruct |
||||
|
| DownTrayStepStruct |
||||
|
| AddLiquidStepStruct |
||||
|
| MoveToSolStepStruct |
||||
|
| MoveToHeaterStepStruct |
||||
|
| ShakingStepStruct |
||||
|
| StartHeatingStepStruct |
||||
|
| StopHeatingStepStruct |
||||
|
| TakePhotoStepStruct |
||||
|
| DelayStepStruct; |
||||
|
|
||||
|
export type StepCmd = StepStruct["method"]; |
||||
|
|
||||
|
export const StepCmdDescMap: { [k in StepCmd]: string } = { |
||||
|
upTray: "抬起托盘", |
||||
|
downTray: "降下托盘", |
||||
|
addLiquid: "添加溶液", |
||||
|
moveToSol: "移至加液", |
||||
|
moveToHeat: "移至加热", |
||||
|
shaking: "摇匀", |
||||
|
startHeating: "开始加热", |
||||
|
stopHeating: "停止加热", |
||||
|
takePhoto: "拍照", |
||||
|
delay: "等待", |
||||
|
}; |
||||
|
|
||||
|
export const CmdDescMap: { [k in OperationCmd]: string } = { |
||||
|
upTray: "抬起托盘", |
||||
|
downTray: "降下托盘", |
||||
|
injectFluid: "注入溶液", |
||||
|
moveToActionArea: "移至操作区", |
||||
|
startShakeUp: "开始摇匀", |
||||
|
stopShakeUp: "结束摇匀", |
||||
|
startHeat: "开始加热", |
||||
|
stopHeat: "停止加热", |
||||
|
// keepHeat: "恒温",
|
||||
|
takePhoto: "拍照", |
||||
|
// moveToUnusual: "移至异常区",
|
||||
|
moveToHeatArea: "移至加热区", |
||||
|
takeOffCap: "取下拍子", |
||||
|
putBackCap: "装回拍子", |
||||
|
openClaw: "张开夹爪", |
||||
|
closeClaw: "收合夹爪", |
||||
|
moveMachineArm: "移动机械臂", |
||||
|
moveTube: "移动试管", |
||||
|
openDoor: "开门", |
||||
|
closeDoor: "关门", |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
export type OperationCmd = |
||||
|
| "upTray" // 抬起托盘
|
||||
|
| "downTray" // 降下托盘
|
||||
|
| "injectFluid" // 注入溶液
|
||||
|
| "moveToActionArea" // 移至操作区
|
||||
|
| "startShakeUp" // 开始摇匀
|
||||
|
| "stopShakeUp" // 结束摇匀
|
||||
|
| "startHeat" // 开始加热
|
||||
|
| "stopHeat" // 停止加热
|
||||
|
// | "keepHeat" // 恒温
|
||||
|
| "takePhoto" // 拍照
|
||||
|
// | "moveToUnusual" // 移至异常区
|
||||
|
| "moveToHeatArea" // 移至加热区
|
||||
|
| "takeOffCap" // 取下拍子
|
||||
|
| "putBackCap" // 装回拍子
|
||||
|
| "openClaw" // 张开夹爪
|
||||
|
| "closeClaw" // 收合夹爪
|
||||
|
| "moveMachineArm" // 移动机械臂
|
||||
|
| "moveTube" // 移动试管
|
||||
|
| "openDoor" //开门
|
||||
|
| "closeDoor"; //关门
|
@ -0,0 +1,266 @@ |
|||||
|
import type { StepCmd } from "./cmdTypes"; |
||||
|
|
||||
|
export type CmdDatagram = { |
||||
|
type: "cmd"; // 指令
|
||||
|
data: { |
||||
|
commandId: string; |
||||
|
// commandName: DebugCmd;
|
||||
|
status: "D0000" | "D1111"; |
||||
|
message?: string; |
||||
|
// success: boolean;
|
||||
|
}; |
||||
|
}; |
||||
|
|
||||
|
export type CraftDatagram = { |
||||
|
type: "crafts"; |
||||
|
data: { |
||||
|
// 当前工艺执行状态,0 表示未执行,1 表示正在执行,2 表示暂停执行,3 表示停止执行 4:Error, 6: 完成。
|
||||
|
status: 0 | 1 | 2 | 3 | 4 | 6; |
||||
|
// 当前正在执行的具体工艺方法
|
||||
|
method: StepCmd; |
||||
|
// 当前正在执行的工艺步骤索引
|
||||
|
methodIndex: number; |
||||
|
// 加热区 ID
|
||||
|
heatId: number; |
||||
|
}; |
||||
|
}; |
||||
|
|
||||
|
export type WarnDatagram = { |
||||
|
type: "warn"; // 报警
|
||||
|
data: { |
||||
|
code: string; |
||||
|
msg: string; |
||||
|
module: string; |
||||
|
}; |
||||
|
}; |
||||
|
|
||||
|
export type StatusDatagram = { |
||||
|
type: "status"; // 状态
|
||||
|
data: { |
||||
|
emergencyStop: boolean; // 硬件急停信号,true 为急停触发,false 为正常运行
|
||||
|
doorStatus: boolean; // 门的状态,false 表示关闭,true 表示开启
|
||||
|
railArm: { |
||||
|
x: number; |
||||
|
y: number; |
||||
|
z: number; |
||||
|
joint1: number; |
||||
|
joint2: number; |
||||
|
distance: number; // 当前机械臂(轴 3)上下移动的距离
|
||||
|
railDistance: number; |
||||
|
clawDistance: number; |
||||
|
clawStatus: boolean; // 夹爪状态,true 为张开,false 为闭合
|
||||
|
isZeroPos: boolean; // 导轨是否在原点
|
||||
|
isLimitPos: boolean; // 导轨是否在限位点
|
||||
|
}; |
||||
|
// 操作区(加液、摇匀、拍照)状态
|
||||
|
liquidArea: { |
||||
|
liquidArm: { |
||||
|
x: number; |
||||
|
y: number; |
||||
|
z: number; |
||||
|
joint1: number; |
||||
|
joint2: number; |
||||
|
pump: Array<{ |
||||
|
pumpId: number; |
||||
|
isPumping: boolean; // 是否正在加液,true正在加液
|
||||
|
}>; |
||||
|
}; |
||||
|
isShaking: boolean; // 是否正在摇匀
|
||||
|
liquidTray: boolean; // 是否存在托盘
|
||||
|
// 溶液容器状态
|
||||
|
solutionBucket: Array<{ |
||||
|
isEmpty: boolean; // 容器是否为空
|
||||
|
isFull: boolean; // 容器是否已满
|
||||
|
}>; |
||||
|
}; |
||||
|
|
||||
|
// 加热区列表
|
||||
|
heatArea: Array<{ |
||||
|
// heaterId: string;
|
||||
|
hardwareId: string; |
||||
|
trayStatus: 0 | 1 | 2; // 0为无托盘,1为有托盘,2为托盘抬起
|
||||
|
isHeating: boolean; // 是否正在加热
|
||||
|
capStatus: boolean; // 是否存在拍子
|
||||
|
isSealed: boolean; // 拍子密封状态,true为已密封,false为未密封
|
||||
|
temperature: number; // 当前温度
|
||||
|
}>; |
||||
|
// 碱容器状态(废液桶)
|
||||
|
alkaliBucket: { |
||||
|
isEmpty: boolean; // 容器是否为空
|
||||
|
isFull: boolean; // 容器是否已满
|
||||
|
}; |
||||
|
}; |
||||
|
}; |
||||
|
|
||||
|
export type CraftState = { |
||||
|
type: "crafts"; |
||||
|
data: { |
||||
|
heatId: string | number; |
||||
|
methodIndex: string | number; |
||||
|
status: string | number; |
||||
|
}; |
||||
|
}; |
||||
|
|
||||
|
export type ContainerDatagram = { |
||||
|
type: "container"; |
||||
|
data: { |
||||
|
containerList: Array<{ |
||||
|
id: number; |
||||
|
type: 0 | 1; // 0:酸液 1:废液
|
||||
|
solutionId: number; |
||||
|
pumpId: number; |
||||
|
capacityTotal: number; |
||||
|
capacityUsed: number; |
||||
|
}>; |
||||
|
}; |
||||
|
}; |
||||
|
|
||||
|
export type Datagram = CmdDatagram | WarnDatagram | StatusDatagram | CraftDatagram | ContainerDatagram; |
||||
|
|
||||
|
export const defaultStatus: StatusDatagram["data"] = { |
||||
|
emergencyStop: false, // 硬件急停信号,true 为急停触发,false 为正常运行
|
||||
|
doorStatus: false, // 门的状态,false 表示关闭,true 表示开启
|
||||
|
railArm: { |
||||
|
x: 0, |
||||
|
y: 0, |
||||
|
z: 0, |
||||
|
joint1: 0, |
||||
|
joint2: 0, |
||||
|
distance: 0, // 当前机械臂(轴 3)上下移动的距离
|
||||
|
railDistance: 0, |
||||
|
clawDistance: 0, |
||||
|
clawStatus: false, // 夹爪状态,true 为张开,false 为闭合
|
||||
|
isZeroPos: true, // 导轨是否在原点
|
||||
|
isLimitPos: false, // 导轨是否在限位点
|
||||
|
}, |
||||
|
// 操作区(加液、摇匀、拍照)状态
|
||||
|
liquidArea: { |
||||
|
liquidArm: { |
||||
|
x: 0, |
||||
|
y: 0, |
||||
|
z: 0, |
||||
|
joint1: 0, |
||||
|
joint2: 0, |
||||
|
pump: [ |
||||
|
{ |
||||
|
pumpId: 1, |
||||
|
isPumping: false, // 是否正在加液,true正在加液
|
||||
|
}, |
||||
|
{ |
||||
|
pumpId: 2, |
||||
|
isPumping: false, // 是否正在加液,true正在加液
|
||||
|
}, |
||||
|
{ |
||||
|
pumpId: 3, |
||||
|
isPumping: false, // 是否正在加液,true正在加液
|
||||
|
}, |
||||
|
{ |
||||
|
pumpId: 4, |
||||
|
isPumping: false, // 是否正在加液,true正在加液
|
||||
|
}, |
||||
|
{ |
||||
|
pumpId: 5, |
||||
|
isPumping: false, // 是否正在加液,true正在加液
|
||||
|
}, |
||||
|
{ |
||||
|
pumpId: 6, |
||||
|
isPumping: false, // 是否正在加液,true正在加液
|
||||
|
}, |
||||
|
], |
||||
|
}, |
||||
|
isShaking: false, // 是否正在摇匀
|
||||
|
liquidTray: false, // 是否存在托盘
|
||||
|
// 溶液容器状态
|
||||
|
solutionBucket: [ |
||||
|
{ |
||||
|
isEmpty: false, // 容器是否为空
|
||||
|
isFull: false, // 容器是否已满
|
||||
|
}, |
||||
|
{ |
||||
|
isEmpty: false, // 容器是否为空
|
||||
|
isFull: false, // 容器是否已满
|
||||
|
}, |
||||
|
{ |
||||
|
isEmpty: false, // 容器是否为空
|
||||
|
isFull: false, // 容器是否已满
|
||||
|
}, |
||||
|
{ |
||||
|
isEmpty: false, // 容器是否为空
|
||||
|
isFull: false, // 容器是否已满
|
||||
|
}, |
||||
|
{ |
||||
|
isEmpty: false, // 容器是否为空
|
||||
|
isFull: false, // 容器是否已满
|
||||
|
}, |
||||
|
{ |
||||
|
isEmpty: false, // 容器是否为空
|
||||
|
isFull: false, // 容器是否已满
|
||||
|
}, |
||||
|
{ |
||||
|
isEmpty: false, // 容器是否为空
|
||||
|
isFull: false, // 容器是否已满
|
||||
|
}, |
||||
|
{ |
||||
|
isEmpty: false, // 容器是否为空
|
||||
|
isFull: false, // 容器是否已满
|
||||
|
}, |
||||
|
], |
||||
|
}, |
||||
|
|
||||
|
// 加热区列表
|
||||
|
heatArea: [ |
||||
|
{ |
||||
|
hardwareId: "hardware_1", |
||||
|
trayStatus: 0, // 0为无托盘,1为有托盘,2为托盘抬起
|
||||
|
isHeating: false, // 是否正在加热
|
||||
|
capStatus: false, // 是否存在拍子
|
||||
|
isSealed: false, // 拍子密封状态,true为已密封,false为未密封
|
||||
|
temperature: 0, // 当前温度
|
||||
|
}, |
||||
|
{ |
||||
|
hardwareId: "hardware_2", |
||||
|
trayStatus: 0, // 0为无托盘,1为有托盘,2为托盘抬起
|
||||
|
isHeating: false, // 是否正在加热
|
||||
|
capStatus: false, // 是否存在拍子
|
||||
|
isSealed: false, // 拍子密封状态,true为已密封,false为未密封
|
||||
|
temperature: 0, // 当前温度
|
||||
|
}, |
||||
|
{ |
||||
|
hardwareId: "hardware_3", |
||||
|
trayStatus: 0, // 0为无托盘,1为有托盘,2为托盘抬起
|
||||
|
isHeating: false, // 是否正在加热
|
||||
|
capStatus: false, // 是否存在拍子
|
||||
|
isSealed: false, // 拍子密封状态,true为已密封,false为未密封
|
||||
|
temperature: 0, // 当前温度
|
||||
|
}, |
||||
|
{ |
||||
|
hardwareId: "hardware_4", |
||||
|
trayStatus: 0, // 0为无托盘,1为有托盘,2为托盘抬起
|
||||
|
isHeating: false, // 是否正在加热
|
||||
|
capStatus: false, // 是否存在拍子
|
||||
|
isSealed: false, // 拍子密封状态,true为已密封,false为未密封
|
||||
|
temperature: 0, // 当前温度
|
||||
|
}, |
||||
|
{ |
||||
|
hardwareId: "hardware_5", |
||||
|
trayStatus: 0, // 0为无托盘,1为有托盘,2为托盘抬起
|
||||
|
isHeating: false, // 是否正在加热
|
||||
|
capStatus: false, // 是否存在拍子
|
||||
|
isSealed: false, // 拍子密封状态,true为已密封,false为未密封
|
||||
|
temperature: 0, // 当前温度
|
||||
|
}, |
||||
|
{ |
||||
|
hardwareId: "hardware_6", |
||||
|
trayStatus: 0, // 0为无托盘,1为有托盘,2为托盘抬起
|
||||
|
isHeating: false, // 是否正在加热
|
||||
|
capStatus: false, // 是否存在拍子
|
||||
|
isSealed: false, // 拍子密封状态,true为已密封,false为未密封
|
||||
|
temperature: 0, // 当前温度
|
||||
|
}, |
||||
|
], |
||||
|
// 碱容器状态(废液桶)
|
||||
|
alkaliBucket: { |
||||
|
isEmpty: false, // 容器是否为空
|
||||
|
isFull: false, // 容器是否已满
|
||||
|
}, |
||||
|
}; |
@ -0,0 +1,7 @@ |
|||||
|
export async function delay(mill: number) { |
||||
|
return new Promise(resolve => { |
||||
|
setTimeout(() => { |
||||
|
resolve({}); |
||||
|
}, mill); |
||||
|
}); |
||||
|
} |
@ -0,0 +1,11 @@ |
|||||
|
import { Server } from "ws"; |
||||
|
import { Datagram } from "../types/wsTypes"; |
||||
|
|
||||
|
export function wsSend(wss: Server, data: Datagram) { |
||||
|
// 广播消息给所有连接的客户端
|
||||
|
wss.clients.forEach(client => { |
||||
|
if (client.readyState === client.OPEN) { |
||||
|
client.send(JSON.stringify(data)); |
||||
|
} |
||||
|
}); |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue