10 changed files with 1699 additions and 433 deletions
-
12public/index.html
-
37public/main.js
-
25src/index.ts
-
60src/routes/auth.ts
-
18src/routes/cmd.ts
-
59src/routes/debug.ts
-
142src/types/cmdTypes.ts
-
275src/types/wsTypes.ts
-
1503src/utils/measure.json
-
1tsconfig.json
@ -0,0 +1,60 @@ |
|||||
|
import express from "express"; |
||||
|
const router = express.Router(); |
||||
|
import { wsSend } from "../utils/wss"; |
||||
|
import { delay } from "../utils/helper"; |
||||
|
|
||||
|
router.post("/login", async (req, res) => { |
||||
|
console.log("/login:", req.body); |
||||
|
req.app.locals["context"] = { |
||||
|
loginFlag: true, |
||||
|
loginUser: { |
||||
|
id: 0, |
||||
|
account: "Demo", |
||||
|
nickname: "Demo", |
||||
|
password: "Demo", |
||||
|
userRole: "Admin", |
||||
|
isBuiltInUser: false, |
||||
|
}, |
||||
|
}; |
||||
|
|
||||
|
wsSend(req.app.locals["wss"], { |
||||
|
messageType: "DeviceContext", |
||||
|
data: req.app.locals["context"], |
||||
|
path: "/deviceContext", |
||||
|
}); |
||||
|
|
||||
|
await delay(200); |
||||
|
|
||||
|
res.json({ |
||||
|
status: 0, |
||||
|
data: { |
||||
|
id: 3, //数据主键id
|
||||
|
createTime: "2025-03-03 17:51:13", //数据创建时间
|
||||
|
updateTime: "2025-03-03 19:22:35", //数据更新时间
|
||||
|
account: "test001", //用户账户
|
||||
|
nickname: "测试账户001", //用户昵称
|
||||
|
password: null, |
||||
|
usrRole: "Admin", //用户角色,可用值:User,Admin,Dev
|
||||
|
isBuiltInUser: false, //是否内置用户(内置用户不可删除)
|
||||
|
}, |
||||
|
timestamp: 1741001321389, |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
router.post("/logout", (req, res) => { |
||||
|
req.app.locals["context"] = { |
||||
|
loginFlag: false, |
||||
|
loginUser: {}, |
||||
|
}; |
||||
|
wsSend(req.app.locals["wss"], { |
||||
|
messageType: "DeviceContext", |
||||
|
data: req.app.locals["context"], |
||||
|
path: "/deviceContext", |
||||
|
}); |
||||
|
|
||||
|
res.json({ |
||||
|
status: 0, |
||||
|
timestamp: 1741005358167, |
||||
|
}); |
||||
|
}); |
||||
|
export default router; |
@ -1,142 +0,0 @@ |
|||||
|
|
||||
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"; //关门
|
|
@ -1,266 +1,41 @@ |
|||||
import type { StepCmd } from "./cmdTypes"; |
|
||||
|
|
||||
export type CmdDatagram = { |
|
||||
type: "cmd"; // 指令
|
|
||||
|
// 开始、停止绘制
|
||||
|
export type TaskState = { |
||||
|
messageType: "EVENT"; |
||||
data: { |
data: { |
||||
commandId: string; |
|
||||
// commandName: DebugCmd;
|
|
||||
status: "D0000" | "D1111"; |
|
||||
message?: string; |
|
||||
// success: boolean;
|
|
||||
|
event: "START_RECORD_SIG" | "END_RECORD_SIG"; |
||||
}; |
}; |
||||
|
path: "/measurement-task/get-task-state"; |
||||
}; |
}; |
||||
|
|
||||
export type CraftDatagram = { |
|
||||
type: "crafts"; |
|
||||
|
// 连接上报坐标点
|
||||
|
export type TrackRecordSig = { |
||||
|
messageType: "EVENT"; |
||||
data: { |
data: { |
||||
// 当前工艺执行状态,0 表示未执行,1 表示正在执行,2 表示暂停执行,3 表示停止执行 4:Error, 6: 完成。
|
|
||||
status: 0 | 1 | 2 | 3 | 4 | 6; |
|
||||
// 当前正在执行的具体工艺方法
|
|
||||
method: StepCmd; |
|
||||
// 当前正在执行的工艺步骤索引
|
|
||||
methodIndex: number; |
|
||||
// 加热区 ID
|
|
||||
heatId: number; |
|
||||
|
x: number; |
||||
|
y: number; |
||||
}; |
}; |
||||
|
path: "/measurement-task/profile-record-ctrl-sig"; |
||||
}; |
}; |
||||
|
|
||||
export type WarnDatagram = { |
|
||||
type: "warn"; // 报警
|
|
||||
data: { |
|
||||
code: string; |
|
||||
msg: string; |
|
||||
module: string; |
|
||||
}; |
|
||||
|
export const defaultContext: ContextMessage["data"] = { |
||||
|
loginFlag: false, |
||||
|
loginUser: {}, |
||||
}; |
}; |
||||
|
|
||||
export type StatusDatagram = { |
|
||||
type: "status"; // 状态
|
|
||||
|
export type ContextMessage = { |
||||
|
messageType: "DeviceContext"; |
||||
data: { |
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<{ |
|
||||
|
loginFlag: Boolean; |
||||
|
loginUser: Partial<{ |
||||
id: number; |
id: number; |
||||
type: 0 | 1; // 0:酸液 1:废液
|
|
||||
solutionId: number; |
|
||||
pumpId: number; |
|
||||
capacityTotal: number; |
|
||||
capacityUsed: number; |
|
||||
|
account: string; |
||||
|
nickname: string; |
||||
|
password: string; |
||||
|
userRole: "Admin" | "User" | "Dev"; |
||||
|
isBuiltInUser: boolean; |
||||
}>; |
}>; |
||||
}; |
}; |
||||
|
path: "/deviceContext"; |
||||
}; |
}; |
||||
|
|
||||
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, // 容器是否已满
|
|
||||
}, |
|
||||
}; |
|
||||
|
export type Datagram = TrackRecordSig | TaskState | ContextMessage; |
1503
src/utils/measure.json
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
Write
Preview
Loading…
Cancel
Save
Reference in new issue