Browse Source

ServerView 服务器状态管理、ConnectEnv 连接状态分离、Authorization 服务授权、

master
修宁 5 months ago
parent
commit
d722680273
  1. 79
      servo/src/main/java/com/galaxis/rcs/ptr/PtrAgvItem.java
  2. 89
      servo/src/main/java/com/yvan/entity/AgvStatusVo.java
  3. 12
      servo/src/main/java/com/yvan/entity/ServerAuthorizationConfigVo.java
  4. 96
      servo/src/main/java/com/yvan/entity/ServerStatusVo.java
  5. 2
      servo/src/main/java/com/yvan/logisticsEnv/EnvConfig.java
  6. 28
      servo/src/main/java/com/yvan/logisticsModel/LogisticsRuntime.java
  7. 7
      servo/src/main/java/com/yvan/logisticsModel/LogisticsRuntimeService.java
  8. 56
      servo/src/main/java/com/yvan/logisticsModel/RuntimeState.java
  9. 8
      servo/src/main/java/com/yvan/pusher/FrontendMessagePushService.java
  10. 1
      servo/src/main/java/com/yvan/redis/LccRedisService.java
  11. 10
      servo/src/main/java/com/yvan/workbench/autoconfigure/LccConfigProperties.java
  12. 29
      servo/src/main/java/com/yvan/workbench/controller/AuthController.java
  13. 136
      servo/src/main/java/com/yvan/workbench/controller/LccController.java
  14. 11
      servo/src/main/java/com/yvan/workbench/controller/LccModelManager.java
  15. 151
      servo/src/main/java/com/yvan/workbench/controller/ServerController.java
  16. 2
      servo/src/main/java/com/yvan/workbench/service/LccMapService.java
  17. 20
      servo/src/main/resources/application-dev.yml

79
servo/src/main/java/com/galaxis/rcs/ptr/PtrAgvItem.java

@ -19,6 +19,7 @@ import lombok.Getter;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.clever.core.Conv; import org.clever.core.Conv;
import org.clever.core.json.JsonWrapper;
import org.clever.data.redis.Redis; import org.clever.data.redis.Redis;
import org.clever.data.redis.RedisAdmin; import org.clever.data.redis.RedisAdmin;
@ -399,27 +400,18 @@ public abstract class PtrAgvItem extends ExecutorItem {
updateRedisStatus(); updateRedisStatus();
} }
@SneakyThrows
public void updateRedisStatus() { public void updateRedisStatus() {
String statusKey = getRedisKey("status"); String statusKey = getRedisKey("status");
Map<String, String> statusMap = new HashMap<>(); var state = this.getState();
statusMap.put("x", String.valueOf(x)); var statusMap = new JsonWrapper(state).getInnerMap();
statusMap.put("y", String.valueOf(y));
statusMap.put("z", String.valueOf(z));
statusMap.put("logicX", String.valueOf(logicX));
statusMap.put("logicY", String.valueOf(logicY));
statusMap.put("direction", String.valueOf(direction));
statusMap.put("orientation", String.valueOf(orientation));
statusMap.put("soc", this.battery == null ? "-1" : String.valueOf(this.battery.SOC));
statusMap.put("mode", Conv.asString(this.__taskMode));
statusMap.put("taskStatus", getTaskStatus());
redis.hPutAll(statusKey, statusMap); redis.hPutAll(statusKey, statusMap);
} }
public void handleHeartbeat(AmrHeartbeatMessage heartbeat) { public void handleHeartbeat(AmrHeartbeatMessage heartbeat) {
// 更新在线状态 // 更新在线状态
String aliveKey = getRedisKey("alive"); String aliveKey = getRedisKey("alive");
redis.vSet(aliveKey, "1"); redis.vSet(aliveKey, this.runtime.serverId);
redis.kExpire(aliveKey, 5); // 5秒过期 redis.kExpire(aliveKey, 5); // 5秒过期
// 更新状态信息 // 更新状态信息
@ -850,36 +842,37 @@ public abstract class PtrAgvItem extends ExecutorItem {
public AgvStatusVo getState() { public AgvStatusVo getState() {
var ptr = this; var ptr = this;
int taskCompleted = 0;
int taskTotalCount = 0; var state = new AgvStatusVo();
state.setId(ptr.id);
state.setType(ptr.getT());
state.setIsOnline(ptr.isOnline);
state.setIsSystemManaged(ptr.isSystemManaged);
state.setX(ptr.x);
state.setY(ptr.y);
state.setZ(ptr.z);
state.setLogicX(ptr.logicX);
state.setLogicY(ptr.logicY);
state.setDirection(PathUtils.getDirectionByArmDirection(ptr.direction));
state.setOrientation(ptr.orientation);
state.setSoc(ptr.battery == null ? -1 : ptr.battery.SOC);
state.setMode(ptr.get__taskMode());
state.setTaskStatus(ptr.getTaskStatus());
state.setIsBlocked(ptr.isBlocked);
if (ptr.planTaskSequence != null) { if (ptr.planTaskSequence != null) {
taskCompleted = ptr.planTaskSequence.completedCount(); state.setTaskCompleted(ptr.planTaskSequence.completedCount());
taskTotalCount = ptr.planTaskSequence.taskTotalCount(); state.setTaskTotalCount(ptr.planTaskSequence.taskTotalCount());
} state.setBizTaskId(ptr.planTaskSequence.bizTask.getBizTaskId());
return new AgvStatusVo( state.setBizTaskType(BizTaskType.fromString(ptr.planTaskSequence.bizTask.getBizType()));
ptr.id, state.setBizTaskStatus(BizTaskStatus.fromString(ptr.planTaskSequence.bizTask.getBizTaskStatus()));
ptr.getT(), state.setBizTaskFrom(ptr.planTaskSequence.bizTask.getTaskFrom());
ptr.isOnline, state.setBizTaskTo(ptr.planTaskSequence.bizTask.getTaskTo());
ptr.isSystemManaged, state.setBizLpn(ptr.planTaskSequence.bizTask.getLpn());
ptr.x, }
ptr.y,
ptr.z, return state;
ptr.logicX,
ptr.logicY,
PathUtils.getDirectionByArmDirection(ptr.direction),
ptr.orientation,
ptr.battery == null ? 0 : ptr.battery.SOC,
ptr.get__taskMode(),
ptr.getTaskStatus(),
ptr.isBlocked,
taskCompleted,
taskTotalCount,
ptr.planTaskSequence == null ? null : ptr.planTaskSequence.bizTask.getBizTaskId(),
ptr.planTaskSequence == null ? null : BizTaskType.fromString(ptr.planTaskSequence.bizTask.getBizType()),
ptr.planTaskSequence == null ? null : BizTaskStatus.fromString(ptr.planTaskSequence.bizTask.getBizTaskStatus()),
ptr.planTaskSequence == null ? null : ptr.planTaskSequence.bizTask.getTaskFrom(),
ptr.planTaskSequence == null ? null : ptr.planTaskSequence.bizTask.getTaskTo(),
ptr.planTaskSequence == null ? null : ptr.planTaskSequence.bizTask.getLpn()
);
} }
} }

89
servo/src/main/java/com/yvan/entity/AgvStatusVo.java

@ -4,30 +4,71 @@ import com.galaxis.rcs.common.enums.BizTaskStatus;
import com.galaxis.rcs.common.enums.BizTaskType; import com.galaxis.rcs.common.enums.BizTaskType;
import com.galaxis.rcs.common.enums.LCCDirection; import com.galaxis.rcs.common.enums.LCCDirection;
import com.galaxis.rcs.ptr.AmrTaskMode; import com.galaxis.rcs.ptr.AmrTaskMode;
import lombok.Data;
public record AgvStatusVo(String id, @Data
String type, public class AgvStatusVo {
Boolean isOnline, private String id;
Boolean isSystemManaged, private String type;
Double x, private Boolean isOnline;
Double y, private Boolean isSystemManaged;
Double z,
Integer logicX,
Integer logicY,
LCCDirection direction,
Double orientation,
Double soc,
AmrTaskMode mode,
String taskStatus,
Boolean isBlocked,
Integer taskCompleted,
Integer taskTotalCount,
// 业务任务ID
Long bizTaskId,
BizTaskType bizTaskType,
BizTaskStatus bizTaskStatus,
String bizTaskFrom,
String bizTaskTo,
String bizLpn) {
private Double x;
private Double y;
private Double z;
private Integer logicX;
private Integer logicY;
private LCCDirection direction;
private Double orientation;
private Double soc;
private AmrTaskMode mode;
private String taskStatus;
private Boolean isBlocked;
private Integer taskCompleted;
private Integer taskTotalCount;
private Long bizTaskId;
private BizTaskType bizTaskType;
private BizTaskStatus bizTaskStatus;
private String bizTaskFrom;
private String bizTaskTo;
private String bizLpn;
private String virtualLocationAt;
private String virtualExecutorPayload;
public void copyFromExceptVirtual(AgvStatusVo state) {
if (state == null) {
return;
}
this.id = state.id;
this.type = state.type;
this.isOnline = state.isOnline;
this.isSystemManaged = state.isSystemManaged;
this.x = state.x;
this.y = state.y;
this.z = state.z;
this.logicX = state.logicX;
this.logicY = state.logicY;
this.direction = state.direction;
this.orientation = state.orientation;
this.soc = state.soc;
this.mode = state.mode;
this.taskStatus = state.taskStatus;
this.isBlocked = state.isBlocked;
this.taskCompleted = state.taskCompleted;
this.taskTotalCount = state.taskTotalCount;
this.bizTaskId = state.bizTaskId;
this.bizTaskType = state.bizTaskType;
this.bizTaskStatus = state.bizTaskStatus;
this.bizTaskFrom = state.bizTaskFrom;
this.bizTaskTo = state.bizTaskTo;
this.bizLpn = state.bizLpn;
}
} }

12
servo/src/main/java/com/yvan/entity/ServerAuthorizationConfigVo.java

@ -0,0 +1,12 @@
package com.yvan.entity;
import com.yvan.workbench.autoconfigure.LccConfigProperties;
import lombok.Data;
@Data
public class ServerAuthorizationConfigVo {
private String serverId;
private String authorizationCode;
private Long expirationTime;
private LccConfigProperties.FrontendMqtt frontendMqtt;
}

96
servo/src/main/java/com/yvan/entity/ServerStatusVo.java

@ -0,0 +1,96 @@
package com.yvan.entity;
import com.yvan.logisticsEnv.EnvConfig;
import com.yvan.logisticsModel.SystemMetricsStore;
import org.clever.core.mapper.JacksonMapper;
import java.util.HashMap;
import java.util.Map;
/**
* 服务器状态信息
*/
public class ServerStatusVo {
public String projectUuid;
public Long envId;
public Boolean isVirtual;
public String serverId;
public Boolean isRunning;
public Long startTime;
public Long stopTime;
public Float timeRate;
public String[] subSystemList;
public Float cpuUsage;
public Float memoryUsage;
public Float diskIoLoad;
/**
* 空闲内存单位GB
*/
public Float freeMemory;
/**
* 磁盘剩余空间单位GB
*/
public Float diskFreeSpace;
public EnvConfig envConfig;
public String projectLabel;
public void fillSystemInfos() {
this.cpuUsage = SystemMetricsStore.cpuUsage;
this.memoryUsage = SystemMetricsStore.memoryUsage;
this.freeMemory = SystemMetricsStore.freeMemory;
this.diskIoLoad = SystemMetricsStore.diskIoLoad;
this.diskFreeSpace = SystemMetricsStore.diskFreeSpace;
}
public Map<String, Object> toMap() {
Map<String, Object> map = new HashMap<>();
map.put("projectUuid", projectUuid);
map.put("envId", envId);
map.put("isVirtual", isVirtual);
map.put("serverId", serverId);
map.put("isRunning", isRunning);
map.put("startTime", startTime);
map.put("stopTime", stopTime);
map.put("timeRate", timeRate);
map.put("subSystemList", subSystemList);
map.put("cpuUsage", cpuUsage);
map.put("memoryUsage", memoryUsage);
map.put("diskIoLoad", diskIoLoad);
map.put("freeMemory", freeMemory);
map.put("diskFreeSpace", diskFreeSpace);
map.put("envConfig", envConfig != null ? JacksonMapper.getInstance().toJson(envConfig) : null);
map.put("projectLabel", projectLabel);
return map;
}
public void copyFrom(ServerStatusVo state) {
if (state == null) {
return;
}
this.projectUuid = state.projectUuid;
this.envId = state.envId;
this.isVirtual = state.isVirtual;
this.serverId = state.serverId;
this.isRunning = state.isRunning;
this.startTime = state.startTime;
this.stopTime = state.stopTime;
this.timeRate = state.timeRate;
this.subSystemList = state.subSystemList;
this.cpuUsage = state.cpuUsage;
this.memoryUsage = state.memoryUsage;
this.diskIoLoad = state.diskIoLoad;
this.freeMemory = state.freeMemory;
this.diskFreeSpace = state.diskFreeSpace;
this.envConfig = state.envConfig;
this.projectLabel = state.projectLabel;
}
}

2
servo/src/main/java/com/yvan/logisticsEnv/EnvConfig.java

@ -9,8 +9,6 @@ public class EnvConfig implements Serializable {
private MqttConfig mqtt; private MqttConfig mqtt;
private MqttConfig frontendMqtt;
private MysqlConfig mysql; private MysqlConfig mysql;
private RedisConfig redis; private RedisConfig redis;

28
servo/src/main/java/com/yvan/logisticsModel/LogisticsRuntime.java

@ -1,14 +1,11 @@
package com.yvan.logisticsModel; package com.yvan.logisticsModel;
import com.galaxis.rcs.common.entity.RcsTaskPlan; import com.galaxis.rcs.common.entity.RcsTaskPlan;
import com.galaxis.rcs.common.enums.BizTaskStatus;
import com.galaxis.rcs.common.enums.BizTaskType;
import com.galaxis.rcs.common.enums.PlanTaskType; import com.galaxis.rcs.common.enums.PlanTaskType;
import com.galaxis.rcs.connector.cl2.Cl2Item; import com.galaxis.rcs.connector.cl2.Cl2Item;
import com.galaxis.rcs.inv.InvManager; import com.galaxis.rcs.inv.InvManager;
import com.galaxis.rcs.plan.PlanTaskSequence; import com.galaxis.rcs.plan.PlanTaskSequence;
import com.galaxis.rcs.plan.path.NavigationGraph; import com.galaxis.rcs.plan.path.NavigationGraph;
import com.galaxis.rcs.plan.path.PathUtils;
import com.galaxis.rcs.plan.path.PtrPathPlanner; import com.galaxis.rcs.plan.path.PtrPathPlanner;
import com.galaxis.rcs.ptr.AmrMessageHandler; import com.galaxis.rcs.ptr.AmrMessageHandler;
import com.galaxis.rcs.ptr.PtrAgvItem; import com.galaxis.rcs.ptr.PtrAgvItem;
@ -18,13 +15,17 @@ import com.google.common.base.Joiner;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.yvan.entity.AgvStatusVo;
import com.yvan.entity.LccProject; import com.yvan.entity.LccProject;
import com.yvan.entity.LccProjectEnv; import com.yvan.entity.LccProjectEnv;
import com.yvan.entity.ServerStatusVo;
import com.yvan.event.AgvEventManager; import com.yvan.event.AgvEventManager;
import com.yvan.event.AgvEventType; import com.yvan.event.AgvEventType;
import com.yvan.pusher.FrontendMessagePushService; import com.yvan.pusher.FrontendMessagePushService;
import com.yvan.redis.LccRedisService; import com.yvan.redis.LccRedisService;
import com.yvan.workbench.SpringContext;
import com.yvan.workbench.autoconfigure.LccConfigProperties;
import com.yvan.workbench.service.LccMapService;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.clever.core.BannerUtils; import org.clever.core.BannerUtils;
import org.clever.core.Conv; import org.clever.core.Conv;
@ -356,9 +357,12 @@ public class LogisticsRuntime {
// 启动 MQTT 监听 // 启动 MQTT 监听
this.amrMessageHandler.start(this.env.getEnvConfig().getMqtt(), this.serverId); this.amrMessageHandler.start(this.env.getEnvConfig().getMqtt(), this.serverId);
this.frontendMessagePushService.start(this.env.getEnvConfig().getFrontendMqtt(), this.serverId + "_lcc_send");
this.lccRedisService.start(this.env.getEnvConfig().getRedis(), this.serverId); this.lccRedisService.start(this.env.getEnvConfig().getRedis(), this.serverId);
var lccMapService = SpringContext.HOLDER.getBean(LccMapService.class);
LccConfigProperties lccConfigProperties = lccMapService.config;
this.frontendMessagePushService.start(lccConfigProperties.getFrontendMqtt(), this.serverId + "_lcc_send");
// 开启所有机器人的任务处理 // 开启所有机器人的任务处理
Set<String> executorTypes = Sets.newHashSet(); Set<String> executorTypes = Sets.newHashSet();
for (ExecutorItem executorItem : executorItemMap.values()) { for (ExecutorItem executorItem : executorItemMap.values()) {
@ -376,6 +380,9 @@ public class LogisticsRuntime {
// 启动任务指派服务 // 启动任务指派服务
this.taskDispatchFactory.startPolling(); this.taskDispatchFactory.startPolling();
// 推送服务状态
this.frontendMessagePushService.pushServerState(this.getState());
} }
public boolean isRunning() { public boolean isRunning() {
@ -426,9 +433,11 @@ public class LogisticsRuntime {
// 停止 MQTT 监听 // 停止 MQTT 监听
this.amrMessageHandler.stop(); this.amrMessageHandler.stop();
this.frontendMessagePushService.stop();
this.lccRedisService.stop(); this.lccRedisService.stop();
this.frontendMessagePushService.pushServerState(this.getState());
this.frontendMessagePushService.stop();
BannerUtils.printConfig(log, "LogisticsRuntime stop.", new String[]{ BannerUtils.printConfig(log, "LogisticsRuntime stop.", new String[]{
"projectUUID: " + this.projectUuid, "projectUUID: " + this.projectUuid,
"envId: " + this.envId, "envId: " + this.envId,
@ -439,8 +448,8 @@ public class LogisticsRuntime {
}); });
} }
public RuntimeState getState() { public ServerStatusVo getState() {
RuntimeState state = new RuntimeState(); ServerStatusVo state = new ServerStatusVo();
state.projectUuid = this.projectUuid; state.projectUuid = this.projectUuid;
state.envId = this.envId; state.envId = this.envId;
@ -454,6 +463,9 @@ public class LogisticsRuntime {
state.subSystemList = this.project.getSubSystemList(); state.subSystemList = this.project.getSubSystemList();
state.fillSystemInfos(); state.fillSystemInfos();
state.envConfig = this.env.getEnvConfig();
state.projectLabel = this.project.getProjectLabel();
return state; return state;
} }
} }

7
servo/src/main/java/com/yvan/logisticsModel/LogisticsRuntimeService.java

@ -6,6 +6,7 @@ import com.yvan.entity.LccProjectEnv;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import java.net.InetAddress; import java.net.InetAddress;
import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
@ -56,6 +57,12 @@ public class LogisticsRuntimeService {
} }
} }
public List<LogisticsRuntime> getAllRuntimeList() {
synchronized (LOCK) {
return List.copyOf(runtimeMap.values());
}
}
@SneakyThrows @SneakyThrows
public LogisticsRuntime create(LccProject project, LccProjectEnv env) { public LogisticsRuntime create(LccProject project, LccProjectEnv env) {
synchronized (LOCK) { synchronized (LOCK) {

56
servo/src/main/java/com/yvan/logisticsModel/RuntimeState.java

@ -1,56 +0,0 @@
package com.yvan.logisticsModel;
import java.util.HashMap;
import java.util.Map;
public class RuntimeState {
public String projectUuid;
public long envId;
public boolean isVirtual;
public String serverId;
public boolean isRunning;
public long startTime;
public long stopTime;
public float timeRate;
public String[] subSystemList;
public float cpuUsage;
public float memoryUsage;
public float diskIoLoad;
/**
* 空闲内存单位GB
*/
public float freeMemory;
/**
* 磁盘剩余空间单位GB
*/
public float diskFreeSpace;
public void fillSystemInfos() {
this.cpuUsage = SystemMetricsStore.cpuUsage;
this.memoryUsage = SystemMetricsStore.memoryUsage;
this.freeMemory = SystemMetricsStore.freeMemory;
this.diskIoLoad = SystemMetricsStore.diskIoLoad;
this.diskFreeSpace = SystemMetricsStore.diskFreeSpace;
}
public Map<String, Object> toMap() {
Map<String, Object> map = new HashMap<>();
map.put("projectUuid", projectUuid);
map.put("envId", envId);
map.put("isVirtual", isVirtual);
map.put("serverId", serverId);
map.put("isRunning", isRunning);
map.put("startTime", startTime);
map.put("stopTime", stopTime);
map.put("timeRate", timeRate);
map.put("subSystemList", subSystemList);
map.put("cpuUsage", cpuUsage);
map.put("memoryUsage", memoryUsage);
map.put("diskIoLoad", diskIoLoad);
map.put("freeMemory", freeMemory);
map.put("diskFreeSpace", diskFreeSpace);
return map;
}
}

8
servo/src/main/java/com/yvan/pusher/FrontendMessagePushService.java

@ -2,8 +2,10 @@ package com.yvan.pusher;
import com.yvan.entity.AgvStatusVo; import com.yvan.entity.AgvStatusVo;
import com.yvan.entity.BasLocationVo; import com.yvan.entity.BasLocationVo;
import com.yvan.entity.ServerStatusVo;
import com.yvan.logisticsEnv.EnvConfig; import com.yvan.logisticsEnv.EnvConfig;
import com.yvan.logisticsModel.LogisticsRuntime; import com.yvan.logisticsModel.LogisticsRuntime;
import com.yvan.workbench.autoconfigure.LccConfigProperties;
import lombok.Getter; import lombok.Getter;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -24,7 +26,7 @@ import java.util.concurrent.locks.ReentrantLock;
@Slf4j @Slf4j
public class FrontendMessagePushService implements MqttCallback { public class FrontendMessagePushService implements MqttCallback {
private volatile EnvConfig.MqttConfig mqttConfig; private volatile LccConfigProperties.FrontendMqtt mqttConfig;
private volatile String clientId; private volatile String clientId;
private volatile MqttClient mqttClient; private volatile MqttClient mqttClient;
private final LogisticsRuntime runtime; private final LogisticsRuntime runtime;
@ -51,7 +53,7 @@ public class FrontendMessagePushService implements MqttCallback {
* 启动MQTT服务 * 启动MQTT服务
*/ */
@SneakyThrows @SneakyThrows
public void start(EnvConfig.MqttConfig mqttConfig, String clientId) { public void start(LccConfigProperties.FrontendMqtt mqttConfig, String clientId) {
this.mqttConfig = mqttConfig; this.mqttConfig = mqttConfig;
this.clientId = clientId; this.clientId = clientId;
connectionLock.lock(); connectionLock.lock();
@ -138,7 +140,7 @@ public class FrontendMessagePushService implements MqttCallback {
* *
* @param statusData 状态数据 * @param statusData 状态数据
*/ */
public void pushServerState(Map<String, Object> statusData) { public void pushServerState(ServerStatusVo statusData) {
String topic = buildTopic("server"); String topic = buildTopic("server");
publishJson(topic, statusData); publishJson(topic, statusData);
} }

1
servo/src/main/java/com/yvan/redis/LccRedisService.java

@ -81,7 +81,6 @@ public class LccRedisService {
redis.vSet(aliveKey, this.serverId); redis.vSet(aliveKey, this.serverId);
redis.kExpire(aliveKey, 15); // 15秒过期 redis.kExpire(aliveKey, 15); // 15秒过期
heartbeatKeys.put(statusKey, System.currentTimeMillis());
heartbeatKeys.put(aliveKey, System.currentTimeMillis()); heartbeatKeys.put(aliveKey, System.currentTimeMillis());
} }

10
servo/src/main/java/com/yvan/workbench/autoconfigure/LccConfigProperties.java

@ -1,5 +1,6 @@
package com.yvan.workbench.autoconfigure; package com.yvan.workbench.autoconfigure;
import com.yvan.logisticsEnv.EnvConfig;
import lombok.Data; import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
@ -9,10 +10,19 @@ public class LccConfigProperties {
public static final String PREFIX = "lcc"; public static final String PREFIX = "lcc";
private String location; private String location;
private AutoStartItem[] autoStart; private AutoStartItem[] autoStart;
private FrontendMqtt frontendMqtt;
@Data @Data
public static class AutoStartItem { public static class AutoStartItem {
private String projectUuid; private String projectUuid;
private Long envId; private Long envId;
} }
@Data
public static class FrontendMqtt {
private String brokerUrl;
private String username;
private String password;
private String websocket;
}
} }

29
servo/src/main/java/com/yvan/workbench/controller/AuthController.java

@ -0,0 +1,29 @@
package com.yvan.workbench.controller;
import com.yvan.entity.ServerAuthorizationConfigVo;
import com.yvan.workbench.SpringContext;
import com.yvan.workbench.autoconfigure.LccConfigProperties;
import com.yvan.workbench.service.LccMapService;
import lombok.SneakyThrows;
import org.clever.core.model.response.R;
import org.clever.web.mvc.annotation.RequestBody;
import java.net.InetAddress;
import java.util.Map;
public class AuthController {
@SneakyThrows
public static R<ServerAuthorizationConfigVo> getAuthorizationConfig(@RequestBody Map<String, Object> params) {
var lccMapService = SpringContext.HOLDER.getBean(LccMapService.class);
LccConfigProperties lccConfigProperties = lccMapService.config;
ServerAuthorizationConfigVo vo = new ServerAuthorizationConfigVo();
vo.setServerId(InetAddress.getLocalHost().getHostName());
vo.setAuthorizationCode("N/A");
vo.setExpirationTime(0L);
vo.setFrontendMqtt(lccConfigProperties.getFrontendMqtt());
return R.success(vo);
}
}

136
servo/src/main/java/com/yvan/workbench/controller/LccController.java

@ -1,6 +1,6 @@
package com.yvan.workbench.controller; package com.yvan.workbench.controller;
import com.galaxis.rcs.RCSService; import com.galaxis.rcs.common.enums.LCCDirection;
import com.galaxis.rcs.ptr.PtrAgvItem; import com.galaxis.rcs.ptr.PtrAgvItem;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
@ -9,6 +9,7 @@ import com.yvan.logisticsModel.LogisticsRuntimeService;
import com.yvan.workbench.SpringContext; import com.yvan.workbench.SpringContext;
import com.yvan.workbench.service.LccMapService; import com.yvan.workbench.service.LccMapService;
import org.clever.core.Conv; import org.clever.core.Conv;
import org.clever.core.json.JsonWrapper;
import org.clever.core.model.response.R; import org.clever.core.model.response.R;
import org.clever.data.jdbc.DaoFactory; import org.clever.data.jdbc.DaoFactory;
import org.clever.data.jdbc.QueryDSL; import org.clever.data.jdbc.QueryDSL;
@ -29,49 +30,6 @@ import static com.galaxis.rcs.common.query.QLccInvLpn.lccInvLpn;
public class LccController { public class LccController {
static final QueryDSL queryDSL = DaoFactory.getQueryDSL(); static final QueryDSL queryDSL = DaoFactory.getQueryDSL();
public static R<?> getAllProjects() {
var mapService = SpringContext.HOLDER.getBean(LccMapService.class);
return R.success(mapService.getAllProjects());
}
public static R<?> serverStart(@RequestBody Map<String, Object> params) {
String projectUuid = Conv.asString(params.get("projectUUID"));
Long envId = Conv.asLong(params.get("envId"));
if (Strings.isNullOrEmpty(projectUuid)) {
return R.fail("projectUUID Must not be empty");
}
if (envId == null || envId < 0) {
return R.fail("envId Must not be empty");
}
// 启动 RCS 服务器
RCSService.serverStart(projectUuid, envId);
// 启动MFC服务器 / 启动WCS服务器 / 启动PES服务器 等等
return R.success("Project started successfully");
}
public static R<?> serverStop(@RequestBody Map<String, Object> params) {
String projectUuid = Conv.asString(params.get("projectUUID"));
Long envId = Conv.asLong(params.get("envId"));
if (Strings.isNullOrEmpty(projectUuid)) {
return R.fail("projectUUID Must not be empty");
}
if (envId == null || envId < 0) {
return R.fail("envId Must not be empty");
}
// 停止RCS服务器
RCSService.serverStop(projectUuid, envId);
// 停止MFC服务器 / 停止WCS服务器 / 停止PES服务器 等等
return R.success("Project stopped successfully");
}
public static R<?> loadInv(@RequestBody Map<String, Object> params) { public static R<?> loadInv(@RequestBody Map<String, Object> params) {
String catalogCode = Conv.asString(params.get("catalogCode")); String catalogCode = Conv.asString(params.get("catalogCode"));
Long envId = Conv.asLong(params.get("envId")); Long envId = Conv.asLong(params.get("envId"));
@ -111,50 +69,88 @@ public class LccController {
return R.success(list); return R.success(list);
} }
public static R<?> loadExecutor(@RequestBody Map<String, Object> params) { // public static R<?> loadExecutor(@RequestBody Map<String, Object> params) {
// Long envId = Conv.asLong(params.get("envId"));
//
// if (envId == null) {
// return R.fail("envId must not be null");
// }
//
// var list = queryDSL.select(QueryDslUtils.linkedMap(
// lccBasExecutor.executorId,
// lccBasExecutor.virtualFloorCode,
// lccBasExecutor.virtualLocationAt,
// lccBasExecutor.virtualExecutorPayload
// ))
// .from(lccBasExecutor)
// .where(lccBasExecutor.envId.eq(envId))
// .where(lccBasExecutor.isActive.eq(true))
// .fetch();
//
// return R.success(list);
// }
public static R<?> queryDeviceInfoList(@RequestBody Map<String, Object> params) {
String projectUuid = Conv.asString(params.get("projectUUID"));
Long envId = Conv.asLong(params.get("envId")); Long envId = Conv.asLong(params.get("envId"));
if (envId == null) { if (Strings.isNullOrEmpty(projectUuid)) {
return R.fail("envId must not be null"); return R.fail("projectUUID Must not be empty");
}
if (envId == null || envId < 0) {
return R.fail("envId Must not be empty");
} }
var list = queryDSL.select(QueryDslUtils.linkedMap( var list = queryDSL.selectFrom(lccBasExecutor)
lccBasExecutor.executorId,
lccBasExecutor.virtualFloorCode,
lccBasExecutor.virtualLocationAt,
lccBasExecutor.virtualExecutorPayload
))
.from(lccBasExecutor)
.where(lccBasExecutor.envId.eq(envId)) .where(lccBasExecutor.envId.eq(envId))
.where(lccBasExecutor.isActive.eq(true)) .where(lccBasExecutor.isActive.eq(true))
.fetch(); .fetch();
return R.success(list); List<AgvStatusVo> agvStatusList = Lists.newArrayList();
}
public static R<?> queryDeviceInfoList(@RequestBody Map<String, Object> params) { // ==================== 从数据库查询所有的车 ====================
String projectUuid = Conv.asString(params.get("projectUUID")); for (var row : list) {
Long envId = Conv.asLong(params.get("envId")); AgvStatusVo agvStatus = new AgvStatusVo();
agvStatusList.add(agvStatus);
if (Strings.isNullOrEmpty(projectUuid)) { agvStatus.setId(row.getExecutorId());
return R.fail("projectUUID Must not be empty"); agvStatus.setVirtualLocationAt(row.getVirtualLocationAt());
agvStatus.setVirtualExecutorPayload(row.getVirtualExecutorPayload());
agvStatus.setIsOnline(false);
// 1_4:UP
String locationAt = row.getVirtualLocationAt();
// 将 1_4:UP 转换为 LogicX=1 LogicY=4 Direction=UP
if (!Strings.isNullOrEmpty(locationAt)) {
String[] parts = locationAt.split(":");
if (parts.length == 2) {
String[] coords = parts[0].split("_");
if (coords.length == 2) {
agvStatus.setLogicX(Conv.asInteger(coords[0]));
agvStatus.setLogicY(Conv.asInteger(coords[1]));
}
agvStatus.setDirection(LCCDirection.fromString(parts[1]));
} }
if (envId == null || envId < 0) {
return R.fail("envId Must not be empty");
} }
var runtime = LogisticsRuntimeService.INSTANCE.getByProjectEnv(projectUuid, envId); JsonWrapper jw = new JsonWrapper(row.getVirtualExecutorPayload());
if (runtime == null) { agvStatus.setType(jw.asStr("t"));
return R.fail("Project environment is not running");
} }
// 拿到所有的车 // ==================== 获取运行时环境中的车状态 ====================
List<AgvStatusVo> agvStatusList = Lists.newArrayList(); var runtime = LogisticsRuntimeService.INSTANCE.getByProjectEnv(projectUuid, envId);
if (runtime != null) {
for (var executor : runtime.executorItemMap.values()) { for (var executor : runtime.executorItemMap.values()) {
if (executor instanceof PtrAgvItem) { for (var agv : agvStatusList) {
agvStatusList.add(((PtrAgvItem) executor).getState()); if (agv.getId().equals(executor.getId())) {
agv.copyFromExceptVirtual(((PtrAgvItem) executor).getState());
break;
} }
} }
}
}
return R.success(agvStatusList); return R.success(agvStatusList);
} }

11
servo/src/main/java/com/yvan/workbench/controller/LccModelManager.java

@ -32,8 +32,9 @@ public class LccModelManager {
private static Map<String, Object> getOtherData(String projectUuid, String projectLabel) { private static Map<String, Object> getOtherData(String projectUuid, String projectLabel) {
String content = StringUtils.trim(String.format(""" String content = StringUtils.trim(String.format("""
{ {
"project_uuid": "%s", "projectUuid": "%s",
"project_label": "%s", "projectLabel": "%s",
"subSystemList": [ "RCS" ],
"project_version": 0, "project_version": 0,
"server": "demo", "server": "demo",
"Tool": { "Tool": {
@ -126,6 +127,7 @@ public class LccModelManager {
public static R<?> addOrUpdateWorld(@RequestBody Map<String, Object> entity) { public static R<?> addOrUpdateWorld(@RequestBody Map<String, Object> entity) {
String projectUuid = Conv.asString(entity.get("projectUuid")); String projectUuid = Conv.asString(entity.get("projectUuid"));
String projectLabel = Conv.asString(entity.get("projectLabel")); String projectLabel = Conv.asString(entity.get("projectLabel"));
List<String> subSystemList = (List) (entity.get("subSystemList"));
String directoryData = Conv.asString(entity.get("directoryData")); String directoryData = Conv.asString(entity.get("directoryData"));
String envId = Conv.asString(entity.get("envId")); String envId = Conv.asString(entity.get("envId"));
String otherData = Conv.asString(entity.get("otherData")); String otherData = Conv.asString(entity.get("otherData"));
@ -134,9 +136,14 @@ public class LccModelManager {
var lccMapService = SpringContext.HOLDER.getBean(LccMapService.class); var lccMapService = SpringContext.HOLDER.getBean(LccMapService.class);
lccMapService.checkProjectUuid(projectUuid, false); lccMapService.checkProjectUuid(projectUuid, false);
if (subSystemList == null || subSystemList.isEmpty()) {
subSystemList = List.of("RCS");
}
LccProject project = new LccProject(); LccProject project = new LccProject();
project.setProjectUuid(projectUuid); project.setProjectUuid(projectUuid);
project.setProjectLabel(projectLabel); project.setProjectLabel(projectLabel);
project.setSubSystemList(subSystemList.toArray(String[]::new));
project.setProjectFileLocation(""); project.setProjectFileLocation("");
project.setDirectoryData(JacksonMapper.getInstance().fromJson(directoryData, LccProject.CatalogGroup[].class)); project.setDirectoryData(JacksonMapper.getInstance().fromJson(directoryData, LccProject.CatalogGroup[].class));
project.setOtherData(JacksonMapper.getInstance().fromJson(otherData, Map.class)); project.setOtherData(JacksonMapper.getInstance().fromJson(otherData, Map.class));

151
servo/src/main/java/com/yvan/workbench/controller/ServerController.java

@ -0,0 +1,151 @@
package com.yvan.workbench.controller;
import com.galaxis.rcs.RCSService;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.yvan.entity.ServerStatusVo;
import com.yvan.logisticsModel.LogisticsRuntimeService;
import com.yvan.workbench.SpringContext;
import com.yvan.workbench.service.LccMapService;
import org.clever.core.Conv;
import org.clever.core.mapper.BeanCopyUtils;
import org.clever.core.model.response.R;
import org.clever.web.mvc.annotation.RequestBody;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
public class ServerController {
public static R<?> queryServerState(@RequestBody Map<String, Object> params) {
String projectUuid = Conv.asString(params.get("projectUUID"));
long envId = Conv.asLong(params.get("envId"));
var mapService = SpringContext.HOLDER.getBean(LccMapService.class);
// 从文件夹读取全部 项目+环境
List<ServerStatusVo> list = Lists.newArrayList();
if (!Strings.isNullOrEmpty(projectUuid)) {
var proj = mapService.getProjectById(projectUuid);
if (proj == null) {
throw new IllegalArgumentException("Project not found: " + projectUuid);
}
if (envId > 0) {
// 读取指定项目+环境
var env = mapService.getEnvById(projectUuid, envId);
if (env == null) {
throw new IllegalArgumentException("Environment not found: " + envId + " for project: " + projectUuid);
}
ServerStatusVo serverStatus = new ServerStatusVo();
list.add(serverStatus);
serverStatus.projectUuid = proj.getProjectUuid();
serverStatus.projectLabel = proj.getProjectLabel();
serverStatus.subSystemList = proj.getSubSystemList();
serverStatus.envId = env.getEnvId();
serverStatus.isVirtual = env.getIsVirtual();
serverStatus.envConfig = env.getEnvConfig();
serverStatus.isRunning = false;
} else {
// 读取指定项目全部环境
for (var env : mapService.getAllEnv(projectUuid)) {
if (envId > 0 && env.getEnvId() != envId) {
// 读取指定环境
continue;
}
ServerStatusVo serverStatus = new ServerStatusVo();
list.add(serverStatus);
serverStatus.projectUuid = proj.getProjectUuid();
serverStatus.projectLabel = proj.getProjectLabel();
serverStatus.subSystemList = proj.getSubSystemList();
serverStatus.envId = env.getEnvId();
serverStatus.isVirtual = env.getIsVirtual();
serverStatus.envConfig = env.getEnvConfig();
serverStatus.isRunning = false;
}
}
} else {
// 全部项目+环境
for (var proj : mapService.getAllProjects()) {
for (var env : mapService.getAllEnv(proj.getProjectUuid())) {
ServerStatusVo serverStatus = new ServerStatusVo();
list.add(serverStatus);
serverStatus.projectUuid = proj.getProjectUuid();
serverStatus.projectLabel = proj.getProjectLabel();
serverStatus.subSystemList = proj.getSubSystemList();
serverStatus.envId = env.getEnvId();
serverStatus.isVirtual = env.getIsVirtual();
serverStatus.envConfig = env.getEnvConfig();
serverStatus.isRunning = false;
}
}
}
// 从运行时获取详情数据
for (var runtime : LogisticsRuntimeService.INSTANCE.getAllRuntimeList()) {
if (Strings.isNullOrEmpty(runtime.projectUuid)) {
continue; // 跳过没有项目UUID的运行时
}
if (runtime.envId < 0) {
continue; // 跳过没有环境ID的运行时
}
ServerStatusVo serverStatus = null;
for (ServerStatusVo status : list) {
if (status.projectUuid.equals(runtime.projectUuid) && status.envId.equals(runtime.envId)) {
serverStatus = status;
break;
}
}
if (serverStatus != null) {
serverStatus.copyFrom(runtime.getState());
}
}
// list 根据 envId 排序
list.sort(Comparator.comparingLong(a -> a.envId));
return R.success(list);
}
public static R<String> startServer(@RequestBody Map<String, Object> params) {
String projectUuid = Conv.asString(params.get("projectUUID"));
Long envId = Conv.asLong(params.get("envId"));
if (Strings.isNullOrEmpty(projectUuid)) {
return R.fail("projectUUID Must not be empty");
}
if (envId == null || envId < 0) {
return R.fail("envId Must not be empty");
}
// 启动 RCS 服务器
RCSService.serverStart(projectUuid, envId);
// 启动MFC服务器 / 启动WCS服务器 / 启动PES服务器 等等
return R.success("Project started successfully");
}
public static R<String> stopServer(@RequestBody Map<String, Object> params) {
String projectUuid = Conv.asString(params.get("projectUUID"));
Long envId = Conv.asLong(params.get("envId"));
if (Strings.isNullOrEmpty(projectUuid)) {
return R.fail("projectUUID Must not be empty");
}
if (envId == null || envId < 0) {
return R.fail("envId Must not be empty");
}
// 停止RCS服务器
RCSService.serverStop(projectUuid, envId);
// 停止MFC服务器 / 停止WCS服务器 / 停止PES服务器 等等
return R.success("Project stopped successfully");
}
}

2
servo/src/main/java/com/yvan/workbench/service/LccMapService.java

@ -19,7 +19,7 @@ import java.util.Objects;
@Slf4j @Slf4j
public class LccMapService { public class LccMapService {
private final LccConfigProperties config; public final LccConfigProperties config;
public LccMapService(LccConfigProperties lccConfigProperties) { public LccMapService(LccConfigProperties lccConfigProperties) {
this.config = lccConfigProperties; this.config = lccConfigProperties;

20
servo/src/main/resources/application-dev.yml

@ -9,6 +9,11 @@ lcc:
autoStart: autoStart:
# - projectUuid: tw_test # - projectUuid: tw_test
# envId: 1 # envId: 1
frontend-mqtt:
brokerUrl: tcp://127.0.0.1:1883
username: user
password: user
websocket: mqtt://127.0.0.1:7883
mybatis: mybatis:
enable: true enable: true
@ -46,21 +51,6 @@ redis:
database: 0 database: 0
password: 'yxt123456' password: 'yxt123456'
#mqtt:
# broker-url: 'tcp://180.100.199.56:7097'
# client-id: 'luoyifan'
# username: 'galaxis'
# password: 'Admin1234_'
mqtt:
broker-url: 'tcp://10.10.203.239:1885'
client-id: 'yvan-rcs-dev'
username: 'admin'
password: 'admin'
#mqtt:
# broker-url: 'tcp://10.10.8.31:1883'
# client-id: 'yvan-rcs-dev'
# username: 'admin'
# password: 'admin'
web: web:
resources: resources:
enable: true enable: true

Loading…
Cancel
Save