数字孪生后台
This commit is contained in:
189
ruoyi-admin/src/main/java/com/ruoyi/tcp/GetDeviceSsjMap.java
Normal file
189
ruoyi-admin/src/main/java/com/ruoyi/tcp/GetDeviceSsjMap.java
Normal file
@@ -0,0 +1,189 @@
|
||||
package com.ruoyi.tcp;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.ruoyi.common.utils.DictUtils;
|
||||
import com.ruoyi.device.ssj.domain.DeviceSsj;
|
||||
import com.ruoyi.job.domain.MydoJob;
|
||||
import com.ruoyi.job.service.IMydoJobService;
|
||||
import com.ruoyi.schedule.plcRead.ssj.PlcSsjRead;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.io.OutputStream;
|
||||
import java.net.Socket;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
public class GetDeviceSsjMap {
|
||||
private final TcpServerManager manager;
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
private final IMydoJobService mydoJobService;
|
||||
|
||||
/**
|
||||
* 构造函数:注入 TCP 管理器与作业服务,用于管理 3333 端口广播并根据任务号补全物料信息
|
||||
*/
|
||||
public GetDeviceSsjMap(TcpServerManager manager, IMydoJobService mydoJobService) {
|
||||
this.manager = manager;
|
||||
this.mydoJobService = mydoJobService;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化:注册 3333 端口的客户端连接监听,客户端第一次连接时立即发送输送机数据
|
||||
*/
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
manager.setClientListener("port3333", this::handleConnect);
|
||||
}
|
||||
|
||||
/**
|
||||
* 客户端连接处理:构建输送机数据并写入到 Socket 输出流
|
||||
*/
|
||||
private void handleConnect(Socket socket) {
|
||||
try {
|
||||
String payload = readConveyorsFromCache();
|
||||
OutputStream os = socket.getOutputStream();
|
||||
os.write(((payload == null ? "" : payload) + "\n").getBytes(StandardCharsets.UTF_8));
|
||||
os.flush();
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 周期发送:每 2 秒检查 3333 端口是否有连接,有则广播输送机数据,无连接不发送
|
||||
*/
|
||||
@Scheduled(fixedRate = 2000)
|
||||
public void send() {
|
||||
Integer count = manager.status().getOrDefault("port3333", 0);
|
||||
if (count != null && count > 0) {
|
||||
String payload = readConveyorsFromCache();
|
||||
manager.broadcast("port3333", payload == null ? "" : payload);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 PLC 缓存读取输送机状态并组装 JSON
|
||||
* - 工作模式转换为中文标签
|
||||
* - 报警码与文案:使用字典 ssj_ex
|
||||
* - 当任务号有效时,查询 MydoJob 补齐托盘与物料信息
|
||||
* 返回 JSON 字符串格式:{"ssj":[{...}]}
|
||||
*/
|
||||
private String readConveyorsFromCache() {
|
||||
Map<String, DeviceSsj> map = PlcSsjRead.deviceSsjMap;
|
||||
List<SsjDto> list = new ArrayList<>();
|
||||
if (map == null || map.isEmpty()) {
|
||||
return toJson(list);
|
||||
}
|
||||
for (DeviceSsj d : map.values()) {
|
||||
SsjDto dto = new SsjDto();
|
||||
dto.setId(d.getDeviceCode());
|
||||
Integer cf = d.getModel();
|
||||
String mode = "0";
|
||||
if (cf != null) {
|
||||
if (cf == 1) {
|
||||
mode = "手动";
|
||||
}else if (cf == 2) {
|
||||
mode = "自动";
|
||||
}else {
|
||||
mode = String.valueOf(cf);
|
||||
}
|
||||
}
|
||||
dto.setWorkingMode(mode);
|
||||
dto.setTaskNo(String.valueOf(d.getTaskNo()));
|
||||
dto.setRotationDirection(calcRotationDirection(d.getTaskNo()));
|
||||
dto.setAlarm(String.valueOf(d.getException()));
|
||||
dto.setAlarmMsg(DictUtils.getDictLabel("ssj_ex", String.valueOf(d.getException())));
|
||||
dto.setDW(String.valueOf(d.getDw()));
|
||||
dto.setKX(String.valueOf(d.getKx()));
|
||||
if (d.getTaskNo() > 0) {
|
||||
try {
|
||||
MydoJob job = mydoJobService.selectMydoJobByTaskNo(Long.valueOf(d.getTaskNo()));
|
||||
dto.setTrayCode(job == null || job.getTrayCode() == null ? "" : job.getTrayCode());
|
||||
dto.setProductCode(job == null || job.getProductId() == null ? "" : job.getProductId());
|
||||
dto.setProductName(job == null || job.getProductName() == null ? "" : job.getProductName());
|
||||
} catch (Exception e) {
|
||||
dto.setTrayCode("");
|
||||
dto.setProductCode("");
|
||||
dto.setProductName("");
|
||||
}
|
||||
} else {
|
||||
dto.setTrayCode("");
|
||||
dto.setProductCode("");
|
||||
dto.setProductName("");
|
||||
}
|
||||
dto.setRunning("");
|
||||
list.add(dto);
|
||||
}
|
||||
return toJson(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算输送机旋转方向:依据作业 inOrOut 字段,>=20 返回 "2",<20 返回 "1"
|
||||
*/
|
||||
private String calcRotationDirection(int taskNo) {
|
||||
try {
|
||||
if (taskNo <= 0) return "0";
|
||||
MydoJob job = mydoJobService.selectMydoJobByTaskNo((long) taskNo);
|
||||
if (job == null || job.getInOrOut() == null) return "0";
|
||||
int val;
|
||||
try {
|
||||
val = Integer.parseInt(job.getInOrOut());
|
||||
} catch (NumberFormatException e) {
|
||||
return "0";
|
||||
}
|
||||
return val >= 20 ? "2" : "1";
|
||||
} catch (Exception e) {
|
||||
return "0";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表对象序列化为 JSON 字符串
|
||||
*/
|
||||
private String toJson(List<SsjDto> list) {
|
||||
try {
|
||||
Wrapper w = new Wrapper();
|
||||
w.setSsj(list);
|
||||
return objectMapper.writeValueAsString(w);
|
||||
} catch (Exception e) {
|
||||
return "{\"ssj\":[]}";
|
||||
}
|
||||
}
|
||||
|
||||
public static class Wrapper {
|
||||
private List<SsjDto> ssj;
|
||||
/**
|
||||
* 获取输送机列表
|
||||
*/
|
||||
public List<SsjDto> getSsj() { return ssj; }
|
||||
/**
|
||||
* 设置输送机列表
|
||||
*/
|
||||
public void setSsj(List<SsjDto> ssj) { this.ssj = ssj; }
|
||||
}
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public static class SsjDto {
|
||||
private String id;
|
||||
private String workingMode;
|
||||
private String taskNo;
|
||||
private String rotationDirection;
|
||||
private String alarm;
|
||||
private String alarmMsg;
|
||||
private String DW;
|
||||
private String KX;
|
||||
private String running;
|
||||
private String trayCode;
|
||||
private String productCode;
|
||||
private String productName;
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user