opt:西门子车辆状态显示报警信息

This commit is contained in:
2026-03-16 20:29:33 +08:00
parent ff64d2d48c
commit 633304c7f5
19 changed files with 898 additions and 23 deletions

1
.gitignore vendored
View File

@@ -3,3 +3,4 @@ lms/nladmin-system/logPath_IS_UNDEFINED/
acs/nladmin-system/nlsso-server/.idea/ acs/nladmin-system/nlsso-server/.idea/
*.log *.log
lms/nladmin-ui/dist.rar lms/nladmin-ui/dist.rar
lms/.idea/

View File

@@ -97,7 +97,7 @@ public class NDCAgvServiceImpl implements NDCAgvService {
if(null != startStorageCell && null != endStorageCell if(null != startStorageCell && null != endStorageCell
&& "2".equals(startStorageCell.getCar_type())){ && "2".equals(startStorageCell.getCar_type())){
inst.setCar_type("2"); inst.setCar_type("2");
startAddress = deviceService.queryAddressBydeviceCode(inst.getStart_point_code()); startAddress = deviceService.queryEndAddressBydeviceCode(inst.getStart_point_code());
nextAddress = deviceService.queryEndAddressBydeviceCode(inst.getNext_point_code()); nextAddress = deviceService.queryEndAddressBydeviceCode(inst.getNext_point_code());
} else { } else {
inst.setCar_type("1"); inst.setCar_type("1");

View File

@@ -0,0 +1,75 @@
package org.nl.acs.agv_alarm.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.Date;
/**
* AGV报警信息
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("acs_agv_alarm")
public class AcsAgvAlarm implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.ASSIGN_ID)
private String id;
/**
* AGV设备编码
*/
private String deviceCode;
/**
* AGV设备名称
*/
private String deviceName;
/**
* 报警代码
*/
private String alarmCode;
/**
* 报警信息
*/
private String alarmMessage;
/**
* 报警级别: 1-紧急, 2-重要, 3-一般
*/
private String alarmLevel;
/**
* 报警时间
*/
private Date alarmTime;
/**
* 状态: 0-未处理, 1-已处理
*/
private String status;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
/**
* 是否有效: 1-有效, 0-无效
*/
private String isActive;
}

View File

@@ -0,0 +1,70 @@
package org.nl.acs.agv_alarm.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.Date;
/**
* AGV状态
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("acs_agv_status")
public class AcsAgvStatus implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.ASSIGN_ID)
private String id;
/**
* AGV设备编码
*/
private String deviceCode;
/**
* AGV设备名称
*/
private String deviceName;
/**
* 状态
*/
private String status;
/**
* x坐标
*/
private Integer x;
/**
* y坐标
*/
private Integer y;
/**
* 角度
*/
private Integer angle;
/**
* 电量
*/
private Integer electricQty;
/**
* 更新时间
*/
private Date updateTime;
/**
* 是否有效: 1-有效, 0-无效
*/
private String isActive;
}

View File

@@ -0,0 +1,37 @@
package org.nl.acs.agv_alarm.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import org.nl.acs.agv_alarm.domain.AcsAgvAlarm;
import java.util.List;
import java.util.Map;
/**
* AGV报警信息Mapper
*/
public interface AcsAgvAlarmMapper extends BaseMapper<AcsAgvAlarm> {
/**
* 根据设备编码查询报警信息
* @param deviceCode 设备编码
* @return 报警信息列表
*/
List<AcsAgvAlarm> selectByDeviceCode(String deviceCode);
/**
* 根据设备编码和状态查询报警信息
* @param deviceCode 设备编码
* @param status 状态
* @return 报警信息列表
*/
List<AcsAgvAlarm> selectByDeviceCodeAndStatus(String deviceCode, String status);
/**
* 查询最新的报警信息
* @param limit 限制数量
* @return 报警信息列表
*/
List<Map<String, Object>> selectLatestAlarms( int limit);
}

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="org.nl.acs.agv_alarm.mapper.AcsAgvAlarmMapper">
<resultMap id="BaseResultMap" type="org.nl.acs.agv_alarm.domain.AcsAgvAlarm">
<id column="id" property="id" />
<result column="device_code" property="deviceCode" />
<result column="device_name" property="deviceName" />
<result column="alarm_code" property="alarmCode" />
<result column="alarm_message" property="alarmMessage" />
<result column="alarm_level" property="alarmLevel" />
<result column="alarm_time" property="alarmTime" />
<result column="status" property="status" />
<result column="create_time" property="createTime" />
<result column="update_time" property="updateTime" />
<result column="is_active" property="isActive" />
</resultMap>
<select id="selectByDeviceCode" resultMap="BaseResultMap">
SELECT * FROM acs_agv_alarm WHERE device_code = #{deviceCode} ORDER BY alarm_time DESC
</select>
<select id="selectByDeviceCodeAndStatus" resultMap="BaseResultMap">
SELECT * FROM acs_agv_alarm WHERE device_code = #{deviceCode} AND status = #{status} ORDER BY alarm_time DESC
</select>
<select id="selectLatestAlarms" resultType="java.util.Map">
SELECT *
FROM acs_agv_alarm
ORDER BY alarm_time DESC
LIMIT #{limit}
</select>
</mapper>

View File

@@ -0,0 +1,26 @@
package org.nl.acs.agv_alarm.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.nl.acs.agv_alarm.domain.AcsAgvStatus;
import java.util.List;
/**
* AGV状态Mapper
*/
public interface AcsAgvStatusMapper extends BaseMapper<AcsAgvStatus> {
/**
* 查询所有AGV状态
* @return AGV状态列表
*/
List<AcsAgvStatus> selectAllStatus();
/**
* 根据设备编码查询AGV状态
* @param deviceCode 设备编码
* @return AGV状态
*/
AcsAgvStatus selectByDeviceCode(String deviceCode);
}

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="org.nl.acs.agv_alarm.mapper.AcsAgvStatusMapper">
<resultMap id="BaseResultMap" type="org.nl.acs.agv_alarm.domain.AcsAgvStatus">
<id column="id" property="id" />
<result column="device_code" property="deviceCode" />
<result column="device_name" property="deviceName" />
<result column="status" property="status" />
<result column="x" property="x" />
<result column="y" property="y" />
<result column="angle" property="angle" />
<result column="electric_qty" property="electricQty" />
<result column="update_time" property="updateTime" />
<result column="is_active" property="isActive" />
</resultMap>
<select id="selectAllStatus" resultMap="BaseResultMap">
SELECT * FROM acs_agv_status
</select>
<select id="selectByDeviceCode" resultMap="BaseResultMap">
SELECT * FROM acs_agv_status WHERE device_code = #{deviceCode}
</select>
</mapper>

View File

@@ -0,0 +1,60 @@
package org.nl.acs.agv_alarm.rest;
import cn.dev33.satoken.annotation.SaIgnore;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import jdk.nashorn.internal.ir.annotations.Ignore;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.nl.common.logging.annotation.Log;
import org.nl.acs.agv_alarm.service.AcsAgvAlarmService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
/**
* AGV报警信息控制器
*/
@Slf4j
@RestController
@RequiredArgsConstructor
@Api(tags = "AGV报警信息接口")
@SaIgnore
@RequestMapping("/api/agv_alarm")
public class AgvAlarmController {
private final AcsAgvAlarmService agvAlarmService;
@GetMapping("/status")
@Log("获取AGV状态")
@ApiOperation("获取AGV状态")
public ResponseEntity<Object> getAgvStatus() {
return new ResponseEntity<>(agvAlarmService.getAllAgvStatus(), HttpStatus.OK);
}
@GetMapping("/alarms")
@Log("获取AGV报警信息")
@ApiOperation("获取AGV报警信息")
public ResponseEntity<Object> getAgvAlarms(
@RequestParam(required = false) String deviceCode) {
if (deviceCode != null && !deviceCode.isEmpty()) {
return new ResponseEntity<>(agvAlarmService.getAgvAlarms(deviceCode), HttpStatus.OK);
} else {
return new ResponseEntity<>(agvAlarmService.getLatestAlarms(50), HttpStatus.OK);
}
}
@GetMapping("/alarms/latest")
@Log("获取最新报警信息")
@ApiOperation("获取最新报警信息")
public ResponseEntity<Object> getLatestAlarms(
@RequestParam(defaultValue = "10") int limit) {
return new ResponseEntity<>(agvAlarmService.getLatestAlarms(limit), HttpStatus.OK);
}
}

View File

@@ -0,0 +1,63 @@
package org.nl.acs.agv_alarm.service;
import org.nl.acs.agv_alarm.domain.AcsAgvAlarm;
import org.nl.acs.agv_alarm.domain.AcsAgvStatus;
import java.util.List;
import java.util.Map;
/**
* AGV报警信息服务
*/
public interface AcsAgvAlarmService {
/**
* 记录AGV报警信息
* @param deviceCode 设备编码
* @param deviceName 设备名称
* @param alarmCode 报警代码
* @param alarmMessage 报警信息
* @param alarmLevel 报警级别
*/
void recordAlarm(String deviceCode, String deviceName, String alarmCode, String alarmMessage, String alarmLevel);
/**
* 更新AGV状态
* @param deviceCode 设备编码
* @param deviceName 设备名称
* @param status 状态
* @param x x坐标
* @param y y坐标
* @param angle 角度
* @param electricQty 电量
*/
void updateAgvStatus(String deviceCode, String deviceName, int statusInt,String status, int x, int y, int angle, int electricQty);
/**
* 获取AGV状态
* @param deviceCode 设备编码
* @return AGV状态
*/
AcsAgvStatus getAgvStatus(String deviceCode);
/**
* 获取所有AGV状态
* @return AGV状态列表
*/
List<AcsAgvStatus> getAllAgvStatus();
/**
* 获取AGV报警信息
* @param deviceCode 设备编码
* @return 报警信息列表
*/
List<AcsAgvAlarm> getAgvAlarms(String deviceCode);
/**
* 获取最新报警信息
* @param limit 限制数量
* @return 报警信息列表
*/
List<Map<String, Object>> getLatestAlarms(int limit);
}

View File

@@ -0,0 +1,108 @@
package org.nl.acs.agv_alarm.service.impl;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.nl.acs.agv_alarm.domain.AcsAgvAlarm;
import org.nl.acs.agv_alarm.domain.AcsAgvStatus;
import org.nl.acs.agv_alarm.mapper.AcsAgvAlarmMapper;
import org.nl.acs.agv_alarm.mapper.AcsAgvStatusMapper;
import org.nl.acs.agv_alarm.service.AcsAgvAlarmService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* AGV报警信息服务实现
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class AcsAgvAlarmServiceImpl implements AcsAgvAlarmService {
private final AcsAgvAlarmMapper alarmMapper;
private final AcsAgvStatusMapper statusMapper;
@Override
@Transactional(rollbackFor = Exception.class)
public void recordAlarm(String deviceCode, String deviceName, String alarmCode, String alarmMessage, String alarmLevel) {
AcsAgvAlarm alarm = new AcsAgvAlarm();
alarm.setId(IdUtil.simpleUUID());
alarm.setDeviceCode(deviceCode);
alarm.setDeviceName(deviceName);
alarm.setAlarmCode(alarmCode);
alarm.setAlarmMessage(alarmMessage);
alarm.setAlarmLevel(alarmLevel);
alarm.setAlarmTime(new Date());
alarm.setStatus("0");
alarm.setCreateTime(new Date());
alarm.setUpdateTime(new Date());
alarm.setIsActive("1");
alarmMapper.insert(alarm);
log.info("AGV报警信息记录成功: 设备编码={}, 报警代码={}, 报警信息={}", deviceCode, alarmCode, alarmMessage);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updateAgvStatus(String deviceCode, String deviceName,int statusInt, String status, int x, int y, int angle, int electricQty) {
AcsAgvStatus agvStatus = statusMapper.selectByDeviceCode(deviceCode);
Boolean insertFlag = false;
if (agvStatus == null) {
// 创建新的状态记录
insertFlag = true;
agvStatus = new AcsAgvStatus();
agvStatus.setId(IdUtil.simpleUUID());
agvStatus.setDeviceCode(deviceCode);
agvStatus.setDeviceName(deviceName);
}
// 更新状态信息
agvStatus.setStatus(status);
agvStatus.setX(x);
agvStatus.setY(y);
agvStatus.setAngle(angle);
agvStatus.setElectricQty(electricQty);
agvStatus.setUpdateTime(new Date());
if (statusInt == 1 || statusInt == 3 || statusInt == 4 || statusInt == 6 || statusInt == 7) {
agvStatus.setIsActive("1");
} else {
agvStatus.setIsActive("0");
}
if (insertFlag) {
statusMapper.insert(agvStatus);
} else {
statusMapper.updateById(agvStatus);
}
log.debug("AGV状态更新成功: 设备编码={}, 状态={}, 坐标=({},{})", deviceCode, status, x, y);
}
@Override
public AcsAgvStatus getAgvStatus(String deviceCode) {
return statusMapper.selectByDeviceCode(deviceCode);
}
@Override
public List<AcsAgvStatus> getAllAgvStatus() {
return statusMapper.selectAllStatus();
}
@Override
public List<AcsAgvAlarm> getAgvAlarms(String deviceCode) {
return alarmMapper.selectByDeviceCode(deviceCode);
}
@Override
public List<Map<String, Object>> getLatestAlarms(int limit) {
return alarmMapper.selectLatestAlarms(limit);
}
}

View File

@@ -13,6 +13,7 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.nl.acs.AcsConfig; import org.nl.acs.AcsConfig;
import org.nl.acs.agv.server.NDCAgvService; import org.nl.acs.agv.server.NDCAgvService;
import org.nl.acs.agv_alarm.service.AcsAgvAlarmService;
import org.nl.acs.auto.run.OneNDCSocketConnectionAutoRun; import org.nl.acs.auto.run.OneNDCSocketConnectionAutoRun;
import org.nl.acs.device.domain.Device; import org.nl.acs.device.domain.Device;
import org.nl.acs.device.service.DeviceService; import org.nl.acs.device.service.DeviceService;
@@ -72,6 +73,7 @@ public class AgvNdcOneDeviceDriver extends AbstractDeviceDriver implements Devic
DeviceService deviceService = SpringContextHolder.getBean(DeviceService.class); DeviceService deviceService = SpringContextHolder.getBean(DeviceService.class);
ISysDictService dictService = SpringContextHolder.getBean(ISysDictService.class); ISysDictService dictService = SpringContextHolder.getBean(ISysDictService.class);
AcsAgvUsageService agvUsageService = SpringContextHolder.getBean(AcsAgvUsageService.class); AcsAgvUsageService agvUsageService = SpringContextHolder.getBean(AcsAgvUsageService.class);
AcsAgvAlarmService agvAlarmService = SpringContextHolder.getBean(AcsAgvAlarmService.class);
int agvaddr = 0; int agvaddr = 0;
int agvaddr_copy = 0; int agvaddr_copy = 0;
@@ -481,7 +483,7 @@ public class AgvNdcOneDeviceDriver extends AbstractDeviceDriver implements Devic
// AGV使用率统计 - 结束工作 // AGV使用率统计 - 结束工作
try { try {
String agvDeviceCode = "agv" + inst.getCarno(); String agvDeviceCode = "agv" + carno;
if (StrUtil.isNotEmpty(agvDeviceCode)) { if (StrUtil.isNotEmpty(agvDeviceCode)) {
agvUsageService.endWork(agvDeviceCode, inst.getTask_code(), inst.getInstruction_code()); agvUsageService.endWork(agvDeviceCode, inst.getTask_code(), inst.getInstruction_code());
} }
@@ -617,6 +619,35 @@ public class AgvNdcOneDeviceDriver extends AbstractDeviceDriver implements Devic
} else if (phase == 0x74) { } else if (phase == 0x74) {
//三色灯状态 //三色灯状态
status = ikey; status = ikey;
// 更新AGV状态
try {
String agvDeviceCode = "agv" + agvaddr;
String agvDeviceName = this.device_code;
Device agvDevice = deviceAppService.findDeviceByCode(agvDeviceCode);
if (agvDevice != null) {
agvDeviceName = agvDevice.getDevice_name();
}
String statusStr = "正常";
if (status == 1) {
statusStr = "关机";
} else if (status == 2) {
statusStr = "运行中";
}else if (status == 3) {
statusStr = "交通管制";
}else if (status == 4) {
statusStr = "任务等待";
}else if (status == 5) {
statusStr = "充电中";
}else if (status == 6) {
statusStr = "故障中";
}else if (status == 7) {
statusStr = "低电量";
}
agvAlarmService.updateAgvStatus(agvDeviceCode, agvDeviceName, status,statusStr, x, y, angle, electric_qty);
} catch (Exception e) {
log.error("AGV状态更新失败: {}", e.getMessage());
}
} }
if (!ObjectUtil.isEmpty(data)) { if (!ObjectUtil.isEmpty(data)) {
logServer.deviceExecuteLog(this.device_code, "", "", "agvphase:" + phase + "反馈:" + data); logServer.deviceExecuteLog(this.device_code, "", "", "agvphase:" + phase + "反馈:" + data);

View File

@@ -0,0 +1,34 @@
-- AGV报警信息表
CREATE TABLE IF NOT EXISTS acs_agv_alarm (
id VARCHAR(64) NOT NULL COMMENT '主键',
device_code VARCHAR(100) NOT NULL COMMENT 'AGV设备编码',
device_name VARCHAR(200) DEFAULT NULL COMMENT 'AGV设备名称',
alarm_code VARCHAR(50) NOT NULL COMMENT '报警代码',
alarm_message VARCHAR(500) NOT NULL COMMENT '报警信息',
alarm_level VARCHAR(10) DEFAULT '3' COMMENT '报警级别: 1-紧急, 2-重要, 3-一般',
alarm_time DATETIME NOT NULL COMMENT '报警时间',
status VARCHAR(10) DEFAULT '0' COMMENT '状态: 0-未处理, 1-已处理',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
is_active VARCHAR(1) DEFAULT '1' COMMENT '是否有效: 1-有效, 0-无效',
PRIMARY KEY (id),
INDEX idx_device_code (device_code),
INDEX idx_alarm_time (alarm_time),
INDEX idx_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='AGV报警信息表';
-- AGV状态表
CREATE TABLE IF NOT EXISTS acs_agv_status (
id VARCHAR(64) NOT NULL COMMENT '主键',
device_code VARCHAR(100) NOT NULL COMMENT 'AGV设备编码',
device_name VARCHAR(200) DEFAULT NULL COMMENT 'AGV设备名称',
status VARCHAR(50) NOT NULL COMMENT '状态',
x INT DEFAULT 0 COMMENT 'x坐标',
y INT DEFAULT 0 COMMENT 'y坐标',
angle INT DEFAULT 0 COMMENT '角度',
electric_qty INT DEFAULT 0 COMMENT '电量',
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
is_active VARCHAR(1) DEFAULT '1' COMMENT '是否有效: 1-有效, 0-无效',
PRIMARY KEY (id),
UNIQUE INDEX uk_device_code (device_code)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='AGV状态表';

View File

@@ -0,0 +1,18 @@
package org.nl.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
* RestTemplate 配置类
*/
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}

View File

@@ -0,0 +1,61 @@
package org.nl.wms.ext.acs.controller;
import org.nl.common.base.TableDataInfo;
import org.nl.wms.ext.acs.service.AcsAlarmService;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* ACS 报警信息控制器
*/
@RestController
@RequestMapping("/api/acs/alarm")
public class AcsAlarmController {
@Autowired
private AcsAlarmService acsAlarmService;
/**
* 获取 AGV 状态
* @param deviceCode 设备编码
* @return AGV 状态信息
*/
@GetMapping("/status")
public Object getAgvStatus() {
return acsAlarmService.getAgvStatus();
}
/**
* 获取 AGV 报警信息
* @param deviceCode 设备编码
* @return AGV 报警信息列表
*/
@GetMapping("/alarms")
public TableDataInfo getAgvAlarms(@RequestParam String deviceCode) {
List<Object> alarms = acsAlarmService.getAgvAlarms(deviceCode);
TableDataInfo dataInfo = new TableDataInfo();
dataInfo.setContent(alarms);
dataInfo.setTotalElements(alarms.size());
return dataInfo;
}
/**
* 获取最新报警信息
* @param limit 限制数量
* @return 最新报警信息列表
*/
@GetMapping("/alarms/latest")
public TableDataInfo getLatestAlarms(@RequestParam(defaultValue = "10") int limit) {
List<Object> alarms = acsAlarmService.getLatestAlarms(limit);
TableDataInfo dataInfo = new TableDataInfo();
dataInfo.setContent(alarms);
dataInfo.setTotalElements(alarms.size());
return dataInfo;
}
}

View File

@@ -0,0 +1,31 @@
package org.nl.wms.ext.acs.service;
import java.util.List;
/**
* ACS 报警信息服务
*/
public interface AcsAlarmService {
/**
* 获取 AGV 状态
* @param deviceCode 设备编码
* @return AGV 状态信息
*/
Object getAgvStatus();
/**
* 获取 AGV 报警信息
* @param deviceCode 设备编码
* @return AGV 报警信息列表
*/
List<Object> getAgvAlarms(String deviceCode);
/**
* 获取最新报警信息
* @param limit 限制数量
* @return 最新报警信息列表
*/
List<Object> getLatestAlarms(int limit);
}

View File

@@ -0,0 +1,150 @@
package org.nl.wms.ext.acs.service.impl;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.nl.config.SpringContextHolder;
import org.nl.system.service.param.dao.Param;
import org.nl.system.service.param.impl.SysParamServiceImpl;
import org.nl.wms.ext.acs.service.AcsAlarmService;
import org.nl.wms.ext.acs.service.dto.to.wms.AcsResponse;
import org.nl.wms.sch.task_manage.GeneralDefinition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.List;
import java.util.Map;
/**
* ACS 报警信息服务实现
*/
@Service
@Slf4j
public class AcsAlarmServiceImpl implements AcsAlarmService {
@Autowired
private RestTemplate restTemplate;
@Override
public List<Object> getAgvStatus() {
SysParamServiceImpl sysParamService = SpringContextHolder.getBean(SysParamServiceImpl.class);
//判断是否连接ACS系统
Param isConnectAcs = sysParamService.findByCode(GeneralDefinition.IS_CONNECT_ACS);
if (ObjectUtil.isEmpty(isConnectAcs)) {
log.error("参数表中:" + GeneralDefinition.IS_CONNECT_ACS + "不存在");
return null;
}
String isConnect = isConnectAcs.getValue();
//ACS地址127.0.0.1:8010
Param acsUrlObj = sysParamService.findByCode(GeneralDefinition.ACS_URL);
if (ObjectUtil.isEmpty(acsUrlObj)) {
log.error("参数表中:" + GeneralDefinition.ACS_URL + "不存在");
return null;
}
String acsUrl = acsUrlObj.getValue();
if (StrUtil.equals(GeneralDefinition.NO, isConnect)) {
log.error("未连接ACS!");
return null;
}
String url = acsUrl + "api/agv_alarm/status";
try {
// 尝试作为 JSON 数组接收
ResponseEntity<List> response = restTemplate.exchange(url, HttpMethod.GET, null, List.class);
return response.getBody();
} catch (Exception e) {
try {
// 尝试作为 JSON 对象接收
ResponseEntity<Map> response = restTemplate.exchange(url, HttpMethod.GET, null, Map.class);
Map<String, Object> body = response.getBody();
return (List<Object>) body.get("data");
} catch (Exception ex) {
log.error("获取AGV报警信息失败" + ex.getMessage());
return null;
}
}
}
@Override
public List<Object> getAgvAlarms(String deviceCode) {
SysParamServiceImpl sysParamService = SpringContextHolder.getBean(SysParamServiceImpl.class);
//判断是否连接ACS系统
Param isConnectAcs = sysParamService.findByCode(GeneralDefinition.IS_CONNECT_ACS);
if (ObjectUtil.isEmpty(isConnectAcs)) {
log.error("参数表中:" + GeneralDefinition.IS_CONNECT_ACS + "不存在");
return null;
}
String isConnect = isConnectAcs.getValue();
//ACS地址127.0.0.1:8010
Param acsUrlObj = sysParamService.findByCode(GeneralDefinition.ACS_URL);
if (ObjectUtil.isEmpty(acsUrlObj)) {
log.error("参数表中:" + GeneralDefinition.ACS_URL + "不存在");
return null;
}
String acsUrl = acsUrlObj.getValue();
if (StrUtil.equals(GeneralDefinition.NO, isConnect)) {
log.error("未连接ACS!");
return null;
}
String url = acsUrl + "api/agv_alarm/alarms?deviceCode=" + deviceCode;
try {
// 尝试作为 JSON 数组接收
ResponseEntity<List> response = restTemplate.exchange(url, HttpMethod.GET, null, List.class);
return response.getBody();
} catch (Exception e) {
try {
// 尝试作为 JSON 对象接收
ResponseEntity<Map> response = restTemplate.exchange(url, HttpMethod.GET, null, Map.class);
Map<String, Object> body = response.getBody();
return (List<Object>) body.get("data");
} catch (Exception ex) {
log.error("获取AGV报警信息失败" + ex.getMessage());
return null;
}
}
}
@Override
public List<Object> getLatestAlarms(int limit) {
SysParamServiceImpl sysParamService = SpringContextHolder.getBean(SysParamServiceImpl.class);
//判断是否连接ACS系统
Param isConnectAcs = sysParamService.findByCode(GeneralDefinition.IS_CONNECT_ACS);
if (ObjectUtil.isEmpty(isConnectAcs)) {
log.error("参数表中:" + GeneralDefinition.IS_CONNECT_ACS + "不存在");
return null;
}
String isConnect = isConnectAcs.getValue();
//ACS地址127.0.0.1:8010
Param acsUrlObj = sysParamService.findByCode(GeneralDefinition.ACS_URL);
if (ObjectUtil.isEmpty(acsUrlObj)) {
log.error("参数表中:" + GeneralDefinition.ACS_URL + "不存在");
return null;
}
String acsUrl = acsUrlObj.getValue();
if (StrUtil.equals(GeneralDefinition.NO, isConnect)) {
log.error("未连接ACS!");
return null;
}
String url = acsUrl + "api/agv_alarm/alarms/latest?limit=" + limit;
try {
// 尝试作为 JSON 数组接收
ResponseEntity<List> response = restTemplate.exchange(url, HttpMethod.GET, null, List.class);
return response.getBody();
} catch (Exception e) {
try {
// 尝试作为 JSON 对象接收
ResponseEntity<Map> response = restTemplate.exchange(url, HttpMethod.GET, null, Map.class);
Map<String, Object> body = response.getBody();
return (List<Object>) body.get("data");
} catch (Exception ex) {
log.error("获取最新报警信息失败:" + ex.getMessage());
return null;
}
}
}
}

View File

@@ -0,0 +1,29 @@
import request from '@/utils/request'
// 调用 LMS 后端的 API由 LMS 后端调用 ACS 后端
// 获取 AGV 状态
export function getAgvStatus() {
return request({
url: '/api/acs/alarm/status',
method: 'get'
})
}
// 获取 AGV 报警信息
export function getAgvAlarms(deviceCode) {
return request({
url: '/api/acs/alarm/alarms',
method: 'get',
params: { deviceCode }
})
}
// 获取最新报警信息
export function getLatestAlarms(limit = 10) {
return request({
url: '/api/acs/alarm/alarms/latest',
method: 'get',
params: { limit }
})
}

View File

@@ -396,6 +396,7 @@
<script> <script>
import crudProduceScreen from './produceScreen' import crudProduceScreen from './produceScreen'
import {getAgvStatus} from '@/api/agv_alarm'
// import crudProduceScreen from './mork' // import crudProduceScreen from './mork'
export default { export default {
data() { data() {
@@ -631,15 +632,15 @@ export default {
searchOrder() { searchOrder() {
crudProduceScreen.regionOrder(this.popData.device_code, this.searchKey).then(res => { crudProduceScreen.regionOrder(this.popData.device_code, this.searchKey).then(res => {
let data = [...res.content] let data = [...res.content]
// 提取去重后的工序列表 // 提取去重后的工序列表
this.processList = [...new Set(data.map(item => item.region_code).filter(Boolean))] this.processList = [...new Set(data.map(item => item.region_code).filter(Boolean))]
// 根据选中的工序进行筛选 // 根据选中的工序进行筛选
if (this.selectedProcess) { if (this.selectedProcess) {
data = data.filter(item => item.region_code === this.selectedProcess) data = data.filter(item => item.region_code === this.selectedProcess)
} }
this.popList = data this.popList = data
this.show = true this.show = true
}) })
@@ -660,26 +661,46 @@ export default {
}, },
// 检查异常信息 // 检查异常信息
checkErrors() { checkErrors() {
// 从后端获取异常信息 // 从 LMS 后端获取 AGV 报警信息
if (this.screenData && this.screenData.device_code) { getAgvStatus().then(res => {
crudProduceScreen.getExceptionMessage(this.screenData.device_code).then(res => { if (res && res.length > 0) {
// 处理接口返回的异常信息 // 转换报警信息格式先过滤再映射避免undefined
if (res && res.content) { this.errorDetails = res
this.errorDetails = res.content .filter(status => status.isActive === '1') // 先过滤出激活的报警
this.hasError = res.content.length > 0 .map(status => { // 再映射成目标格式
} else { return {
this.errorDetails = [] type: 'AGV报警',
this.hasError = false message: `${status.deviceName || status.deviceCode}: ${status.status}`,
} time: new Date(status.updateTime).toLocaleString('zh-CN')
}).catch(error => { }
console.error('获取异常信息失败:', error) })
this.hasError = this.errorDetails.length > 0
} else {
this.errorDetails = [] this.errorDetails = []
this.hasError = false this.hasError = false
}) }
} else { }).catch(error => {
this.errorDetails = [] console.error('获取AGV报警信息失败:', error)
this.hasError = false // 如果从 LMS 后端获取失败,尝试从 LMS 系统获取
} if (this.screenData && this.screenData.device_code) {
crudProduceScreen.getExceptionMessage(this.screenData.device_code).then(res => {
if (res && res.content) {
this.errorDetails = res.content
this.hasError = res.content.length > 0
} else {
this.errorDetails = []
this.hasError = false
}
}).catch(error => {
console.error('获取异常信息失败:', error)
this.errorDetails = []
this.hasError = false
})
} else {
this.errorDetails = []
this.hasError = false
}
})
}, },
// 定时检查异常 // 定时检查异常
startErrorCheck() { startErrorCheck() {