Merge branch 'agv_twoFloorAgvScreen_acs_dev' into acs_dev

This commit is contained in:
2026-01-26 11:30:33 +08:00
6 changed files with 1424 additions and 15 deletions

View File

@@ -0,0 +1,38 @@
package org.nl.acs.agv.contorller;
import org.nl.acs.agv.service.impl.TwoFloorAgvStatusService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 二楼AGV状态控制器
* 提供HTTP接口获取AGV状态信息
*/
@RestController
@RequestMapping("/api/agv/two-floor")
public class TwoFloorAgvController {
@Autowired
private TwoFloorAgvStatusService agvStatusService;
/**
* 获取所有二楼AGV状态
* @return 所有AGV状态列表
*/
@GetMapping("/status")
public Object getAllAgvStatus() {
return agvStatusService.getAllAgvStatus();
}
/**
* 获取单个AGV状态
* @param vehicleCode AGV车辆代码
* @return AGV状态信息
*/
@GetMapping("/status/{vehicleCode}")
public Object getAgvStatus(String vehicleCode) {
return agvStatusService.getAgvStatus(vehicleCode);
}
}

View File

@@ -0,0 +1,180 @@
package org.nl.acs.agv.domain;
import lombok.Data;
/**
* 二楼AGV状态数据模型
* 用于存储和传输AGV的实时状态信息
*/
@Data
public class TwoFloorAgvStatus {
/**
* AGV车辆代码
*/
private String vehicle_code;
/**
* AGV状态
*/
private String status;
/**
* AGV状态文本描述
*/
private String status_text;
/**
* 当前任务代码
*/
private String task_code;
/**
* 当前指令代码
*/
private String inst_code;
/**
* 当前阶段值
*/
private Integer phase;
/**
* 当前阶段名称
*/
private String phase_name;
/**
* 当前位置
*/
private String address;
/**
* 物料类型
*/
private String material_type;
/**
* 物料数量
*/
private Integer quantity;
/**
* 开始设备代码
*/
private String start_device_code;
/**
* 下一个设备代码
*/
private String next_device_code;
/**
* 是否有错误
*/
private Boolean is_error;
/**
* 错误代码
*/
private String error_code;
/**
* 错误信息
*/
private String error_message;
/**
* 卡住的Action
*/
private String error_action;
/**
* 卡住的Mode
*/
private String error_mode;
/**
* 卡住的move
*/
private String error_move;
/**
* 卡住的error
*/
private String error_error;
/**
* 设备号
*/
private String device_code;
/**
* 期望的Action
*/
private String exp_action;
/**
* 卡住的Mode
*/
private String exp_mode;
/**
* 卡住的move
*/
private String exp_move;
/**
* 卡住的error
*/
private String exp_error;
/**
* 实际Action
*/
private String action;
/**
* 实际Mode
*/
private String mode;
/**
* 实际move
*/
private String move;
/**
* 实际error
*/
private String error;
/**
* 电量
*/
private Integer electric_qty;
private String driver;
/**
* X坐标
*/
private Integer x;
/**
* Y坐标
*/
private Integer y;
/**
* 角度
*/
private Integer angle;
/**
* 区域
*/
private Integer region;
/**
* 是否在线
*/
private Boolean is_online;
/**
* 三色灯状态
*/
private Integer status_light;
}

View File

@@ -0,0 +1,140 @@
package org.nl.acs.agv.service.impl;
import org.nl.acs.agv.domain.TwoFloorAgvStatus;
import org.nl.acs.device_driver.agv.utils.TwoAgvPhase;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 二楼AGV状态管理服务
* 负责管理和更新AGV状态通过HTTP接口提供状态查询
*/
@Service
public class TwoFloorAgvStatusService {
@Autowired
private TwoAgvPhase twoAgvPhase;
/**
* 存储AGV状态信息key为AGV车辆代码
*/
private ConcurrentHashMap<String, TwoFloorAgvStatus> agvStatusMap = new ConcurrentHashMap<>();
/**
* 初始化AGV状态
*/
public TwoFloorAgvStatusService() {
// 初始化二楼的4台AGV
for (int i = 1; i <= 4; i++) {
TwoFloorAgvStatus agvStatus = new TwoFloorAgvStatus();
String vehicleCode = String.format("AGV%02d", i);
agvStatus.setVehicle_code(vehicleCode);
agvStatus.setStatus("idle");
agvStatus.setStatus_text("空闲");
agvStatus.setIs_error(false);
agvStatus.setIs_online(true);
agvStatusMap.put(vehicleCode, agvStatus);
}
}
/**
* 更新AGV状态
* @param agvStatus AGV状态信息
*/
public synchronized void updateAgvStatus(TwoFloorAgvStatus agvStatus) {
if (agvStatus == null || agvStatus.getVehicle_code() == null) {
return;
}
// 处理阶段名称
if (agvStatus.getPhase() != null) {
String phaseName = twoAgvPhase.getPhaseName(agvStatus.getPhase());
agvStatus.setPhase_name(phaseName);
}
// 处理状态文本
this.handleStatusText(agvStatus);
// 更新状态
agvStatusMap.put(agvStatus.getVehicle_code(), agvStatus);
}
/**
* 处理AGV状态文本
*/
private void handleStatusText(TwoFloorAgvStatus agvStatus) {
switch (agvStatus.getStatus()) {
case "running":
agvStatus.setStatus_text("运行中");
break;
case "idle":
agvStatus.setStatus_text("空闲");
break;
case "error":
agvStatus.setStatus_text("异常");
agvStatus.setIs_error(true);
break;
case "charging":
agvStatus.setStatus_text("充电中");
break;
default:
agvStatus.setStatus_text("未知");
break;
}
}
/**
* 获取单个AGV状态
* @param vehicleCode AGV车辆代码
* @return AGV状态信息
*/
public TwoFloorAgvStatus getAgvStatus(String vehicleCode) {
return agvStatusMap.get(vehicleCode);
}
/**
* 获取所有AGV状态
* @return 所有AGV状态列表
*/
public List<TwoFloorAgvStatus> getAllAgvStatus() {
return new ArrayList<>(agvStatusMap.values());
}
/**
* 清除AGV错误信息
*/
public void clearAgvError(int carno) {
String vehicleCode = String.format("AGV%02d", carno);
TwoFloorAgvStatus agvStatus = agvStatusMap.get(vehicleCode);
if (agvStatus != null) {
agvStatus.setIs_error(false);
agvStatus.setError_code(null);
agvStatus.setError_message(null);
agvStatus.setError_action(null);
agvStatus.setError_mode(null);
// 设置错误信息
agvStatus.setDriver(null);
agvStatus.setIs_error(false);
agvStatus.setError_message(null);
agvStatus.setDevice_code(null);
agvStatus.setError_action(null);
agvStatus.setError_mode(null);
agvStatus.setError_move(null);
agvStatus.setError_error(null);
agvStatus.setExp_action(null);
agvStatus.setExp_mode(null);
agvStatus.setExp_move(null);
agvStatus.setExp_error(null);
if ("error".equals(agvStatus.getStatus())) {
agvStatus.setStatus("idle");
agvStatus.setStatus_text("空闲");
}
}
}
}

View File

@@ -4,6 +4,7 @@ import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.nl.acs.AcsConfig;
import org.nl.acs.agv.domain.TwoFloorAgvStatus;
import org.nl.acs.agv.server.NDCAgvService;
import org.nl.acs.device.domain.Device;
import org.nl.acs.device.service.DeviceService;
@@ -17,6 +18,7 @@ import org.nl.acs.instruction.domain.Instruction;
import org.nl.acs.instruction.service.InstructionService;
import org.nl.acs.instruction.service.impl.InstructionServiceImpl;
import org.nl.acs.log.service.DeviceExecuteLogService;
import org.nl.acs.agv.service.impl.TwoFloorAgvStatusService;
import org.nl.acs.opc.DeviceAppService;
import org.nl.config.SpringContextHolder;
import org.nl.config.lucene.service.LuceneExecuteLogService;
@@ -33,10 +35,7 @@ import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.Arrays;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
@@ -80,6 +79,10 @@ public class TwoNDCSocketConnectionAutoRun extends AbstractAutoRunnable {
AutoRunService autoRunService;
@Autowired
LuceneExecuteLogService luceneExecuteLogService;
/**
* 二楼AGV状态管理服务
*/
private TwoFloorAgvStatusService agvStatusService;
@Autowired
ISysDictService dictService;
@@ -106,7 +109,8 @@ public class TwoNDCSocketConnectionAutoRun extends AbstractAutoRunnable {
DeviceAppService deviceAppService = SpringContextHolder.getBean(DeviceAppService.class);
DeviceService deviceService = SpringContextHolder.getBean(DeviceService.class);
DeviceExecuteLogService logServer = SpringContextHolder.getBean(DeviceExecuteLogService.class);
// 初始化AGV状态管理服务
agvStatusService = SpringContextHolder.getBean(TwoFloorAgvStatusService.class);
try {
log.info("2楼1区域AGV系统链接开始");
ip = paramService.findByCode(AcsConfig.AGVURL).getValue();