车辆信息

This commit is contained in:
cbs 2025-02-06 11:04:54 +08:00
parent d29261e7b8
commit aebbd85dbe
19 changed files with 433 additions and 79 deletions

View File

@ -1,15 +1,27 @@
package cn.iododer.yudao.module.mqtt.service;
import cn.iocoder.yudao.module.system.api.robot.RobotGenericsStatusApi;
import cn.iocoder.yudao.module.system.api.robot.RobotStatusApi;
import cn.iocoder.yudao.module.system.api.robot.dto.RobotGenericsDTO;
import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDTO;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
@Slf4j
public class RobotGenericsStatusServiceImpl implements MqttService{
@Resource
private RobotGenericsStatusApi robotGenericsStatusApi;
@Override
public void analysisMessage(String message) {
// log.info("处理RobotGenericsStatusServiceImpl的消息 :{}",message);
log.info("处理RobotGenericsStatusServiceImpl的消息 :{}",message);
RobotGenericsDTO robotStatusData = JSON.parseObject(message , RobotGenericsDTO.class);
robotGenericsStatusApi.updateRobotCommonStatus(robotStatusData);
}
}

View File

@ -1,11 +1,20 @@
package cn.iocoder.yudao.module.system.api.robot;
import cn.iocoder.yudao.module.system.api.robot.dto.RobotGenericsDTO;
import cn.iocoder.yudao.module.system.enums.ApiConstants;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿fallbackFactory =
@Tag(name = "RPC 服务 - 机器人异常上报")
@Tag(name = "RPC 服务 - 机器人异常上报/常规信息上报")
public interface RobotGenericsStatusApi {
String PREFIX = ApiConstants.PREFIX + "/task";
@PostMapping(PREFIX + "/updateRobotCommonStatus")
@Operation(summary = "机器人异常上报/常规信息上报")
void updateRobotCommonStatus(@RequestBody RobotGenericsDTO robotStatusData);
}

View File

@ -0,0 +1,24 @@
package cn.iocoder.yudao.module.system.api.robot.dto;
import lombok.Data;
/**
* 车机响应信息
*/
@Data
public class RobotGenericsDTO {
/**
* 错误码
*/
private String status_code;
/**
* 错误信息
*/
private String message;
/**
* 解决方法
*/
private String solution;
private RobotGenericsDataDTO data;
}

View File

@ -0,0 +1,16 @@
package cn.iocoder.yudao.module.system.api.robot.dto;
import lombok.Data;
@Data
public class RobotGenericsDataDTO {
//车身控制器状态
private RobotHwStatesDTO hw_states;
//mac地址
private String mac;
private String ip;
//楼层
private String floor;
//区域
private String zone;
}

View File

@ -0,0 +1,66 @@
package cn.iocoder.yudao.module.system.api.robot.dto;
import lombok.Data;
/**
* 车身控制器状态,详情如下表
*/
@Data
public class RobotHwStatesDTO {
//控制器状态
private String controller_state;
//转向电机角度0 为正前方逆时针正方向顺时针负
private String steer_angle;
//转向电机驱动器错误码
private String steer_error_code;
//行走电机转速m/s
private String walk_motor_vel;
//行走电机电流
private String walk_motor_current;
//行走电机温度
private String walk_motor_temperature;
//行走电机电源单元状态
private String walk_motor_power_unit_state;
//行走电机主接触器状态
private String walk_motor_main_contactor_state;
//行走电机电子制动状态
private String walk_motor_electric_brake_state;
//行走电机锁定开关状态
private String walk_motor_lock_switch_state;
//行走电机驱动器错误码
private String walk_motor_error_code;
//货叉高度
private String fork_height;
//电池的剩余容量
private String bat_soc;
//电池电流
private String bat_current;
//电池电压
private String bat_voltage;
//电池温度
private String bat_temperature;
//解析后的电池故障码
private String bat_error_code;
//充电接触器闭合 false 为开true 为闭合
private String charge_relay_closed;
//bms 状态电池充电中false 为放电true 为充电
private String bat_charging;
//货物到位传感器触发状态被按下则 true否则 false
private String cargo_detected;
//叉尖传感器触发状态物体接近触发为 true否则为 false
private String fork_tip_sensor_state;
//急停按键状态按下为 true松开为 false
private String estop_button_state;
//启动按键状态按下为 true松开为 false
private String start_button_state;
//复位按键状态按下为 true松开为 false
private String reset_button_state;
//手动模式拨杆状态true 表示在手动状态false 为自动
private String manual_switch_state;
//转向电机零位传感器状态true 为触发false 为未触发
private String steer_sensor_state;
//碰撞传感器触发状态触发为 true否则为 false
private String bumper_sensor_state;
//灯条状态代码
private String led_state;
}

View File

@ -10,6 +10,10 @@ public class RobotStatusDataPoseDTO {
public String y;
public String x;
public String yaw;
//楼层
public String floor;
//区域
public String area;
//电池剩余容量
public String bat_soc;
}

View File

@ -0,0 +1,47 @@
package cn.iocoder.yudao.module.system.api.robot;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.module.system.api.robot.dto.RobotGenericsDTO;
import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDataPoseDTO;
import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant;
import cn.iocoder.yudao.module.system.util.redis.RedisUtil;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@Slf4j
@RestController // 提供 RESTful API 接口 Feign 调用
@Validated
public class RobotGenericsStatusApiImpl implements RobotGenericsStatusApi {
@Resource
private RedisUtil redisUtil;
@Resource@Value("${zn.robot_position_cache_time:600}")
private Long robotPositionCacheTime;
@Override
public void updateRobotCommonStatus(RobotGenericsDTO robotStatusData) {
if (ObjectUtil.isEmpty(robotStatusData) || ObjectUtil.isEmpty(robotStatusData.getData())
|| ObjectUtil.isEmpty(robotStatusData.getData().getMac())) {
log.info("参数不全 :{}", JSON.toJSONString(robotStatusData));
}
String mac = robotStatusData.getData().getMac();
String pose2dKey = RobotTaskChcheConstant.ROBOT_POSE_BAT +mac;
Object object = redisUtil.get(pose2dKey);
RobotStatusDataPoseDTO robotStatusDataPoseDTO= JSONUtil.toBean((String)object, RobotStatusDataPoseDTO.class);
robotStatusDataPoseDTO.setArea(robotStatusData.getData().getZone());
robotStatusDataPoseDTO.setFloor(robotStatusData.getData().getFloor());
robotStatusDataPoseDTO.setBat_soc(robotStatusData.getData().getHw_states().getBat_soc());
redisUtil.set(pose2dKey,JSON.toJSONString(robotStatusDataPoseDTO),robotPositionCacheTime);
}
}

View File

@ -1,10 +1,11 @@
package cn.iocoder.yudao.module.system.api.robot;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDTO;
import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDataErrorDTO;
import cn.iocoder.yudao.module.system.constant.robot.RobotStatusCodeConstant;
import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDataPoseDTO;
import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotWarnCodeMappingDO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotWarnMsgDO;
@ -55,17 +56,23 @@ public class RobotStatusApiImpl implements RobotStatusApi {
@Override
public void robotStatusUpdate(RobotStatusDTO robotStatusDataDTO) {
TenantContextHolder.setTenantId(1L);
if (ObjectUtil.isNotNull(robotStatusDataDTO) || RobotStatusCodeConstant.OK.equals(robotStatusDataDTO.getStatus_code())
|| ObjectUtil.isEmpty(robotStatusDataDTO.getMac())) {
if (ObjectUtil.isEmpty(robotStatusDataDTO) || ObjectUtil.isEmpty(robotStatusDataDTO.getMac())) {
log.info("机器人上报的信息不全 :{}", JSON.toJSONString(robotStatusDataDTO));
return;
}
String taskStatusKey = RobotTaskChcheConstant.ROBOT_TASK_STATUS +robotStatusDataDTO.getMac();
String cargoDetectedKey = RobotTaskChcheConstant.ROBOT_CARGO_DETECTED +robotStatusDataDTO.getMac();
String pose2dKey = RobotTaskChcheConstant.ROBOT_POSE2D+robotStatusDataDTO.getMac();
String pose2dKey = RobotTaskChcheConstant.ROBOT_POSE_BAT +robotStatusDataDTO.getMac();
redisUtil.set(taskStatusKey, robotStatusDataDTO.getData().getTask_status(),robotPositionCacheTime);
redisUtil.set(cargoDetectedKey,robotStatusDataDTO.getData().getCargo_detected(),robotPositionCacheTime);
redisUtil.set(pose2dKey,String.valueOf(robotStatusDataDTO.getData().getPose2d()),robotPositionCacheTime);
Object object = redisUtil.get(pose2dKey);
RobotStatusDataPoseDTO robotStatusDataPoseDTO= JSONUtil.toBean((String)object, RobotStatusDataPoseDTO.class);
robotStatusDataPoseDTO.setX(robotStatusDataDTO.getData().getPose2d().getX());
robotStatusDataPoseDTO.setY(robotStatusDataDTO.getData().getPose2d().getY());
robotStatusDataPoseDTO.setYaw(robotStatusDataDTO.getData().getPose2d().getYaw());
redisUtil.set(pose2dKey,JSON.toJSONString(robotStatusDataPoseDTO),robotPositionCacheTime);
if (ObjectUtil.isNotNull(robotStatusDataDTO.getData().getErr_code())) {
List<RobotStatusDataErrorDTO> errCode = robotStatusDataDTO.getData().getErr_code();

View File

@ -1,9 +1,12 @@
package cn.iocoder.yudao.module.system.api.robot;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.module.system.api.robot.dto.RobotCommandStateDTO;
import cn.iocoder.yudao.module.system.api.robot.dto.RobotCompleteTaskDTO;
import cn.iocoder.yudao.module.system.constant.robot.RobotExecutionStateConstant;
import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotInformationDO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDetailDO;
@ -12,6 +15,7 @@ import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotTaskDetailMapper;
import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotTaskMapper;
import cn.iocoder.yudao.module.system.enums.robot.RobotStatusEnum;
import cn.iocoder.yudao.module.system.enums.robot.RobotTaskDetailStatusEnum;
import cn.iocoder.yudao.module.system.util.redis.RedisUtil;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@ -22,6 +26,7 @@ import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
@Slf4j
@RestController // 提供 RESTful API 接口 Feign 调用
@ -37,6 +42,9 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
@Autowired@Resource
private RobotInformationMapper robotInformationMapper;
@Resource
private RedisUtil redisUtil;
/**
* 机器人完成任务上报
* @param robotCompleteTaskDTO
@ -50,6 +58,18 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
if (RobotExecutionStateConstant.UN_DO.equals(robotCompleteTaskDTO.getExecution_state())) {
return CommonResult.success(Boolean.TRUE);
}
String robotDoingActionKey = RobotTaskChcheConstant.ROBOT_DOING_ACTION +robotCompleteTaskDTO.getMac();
List<RobotCommandStateDTO> commandState = robotCompleteTaskDTO.getCommand_state();
if (ObjectUtil.isNotEmpty(commandState)) {
RobotCommandStateDTO robotCommandStateDTO = commandState.stream()
.filter(v -> RobotExecutionStateConstant.DOING.equals(Integer.valueOf(v.getExecution_state())))
.findFirst()
.orElse(null);
if (ObjectUtil.isNotEmpty(robotCommandStateDTO)) {
redisUtil.set(robotDoingActionKey,robotCommandStateDTO.getCommand_type());
}
}
//更新任务状态
RobotTaskDetailDO detailDO = new RobotTaskDetailDO();
detailDO.setId(robotCompleteTaskDTO.getOrder_id());
@ -77,6 +97,7 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
List<RobotInformationDO> existRobotMac = robotInformationMapper.queryAllByLimit(query);
String robotNo = existRobotMac.get(0).getRobotNo();
robotInformationMapper.updateRobotStatus(robotNo, RobotStatusEnum.STAND_BY.getType());
redisUtil.del(robotDoingActionKey);
}
return CommonResult.success(true);

View File

@ -1,8 +1,6 @@
package cn.iocoder.yudao.module.system.constant.robot;
public class RobotTaskChcheConstant {
//机器人电量
public static String ROBOT_ELECTRICITY = "robot:information:electricity";
//机器人能否做任务
public static String ROBOT_TASK_STATUS = "robot:information:task:status";
@ -10,9 +8,12 @@ public class RobotTaskChcheConstant {
//机器人身上是否有货
public static String ROBOT_CARGO_DETECTED = "robot:information:cargo:detected";
//机器人点位
public static String ROBOT_POSE2D = "robot:information:pose2d";
//机器人点位和电量
public static String ROBOT_POSE_BAT = "robot:information:pose2d";
//机器人mac地址和机器人编号映射
public static String ROBOT_NO_MAPPING_MAC = "robot:information:no:mapping:mac";
//机器人正在做的动作
public static String ROBOT_DOING_ACTION = "robot:information:doing:action";
}

View File

@ -1,9 +1,6 @@
package cn.iocoder.yudao.module.system.controller.admin.robot;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotInformationPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotInformationRespVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotInformationSaveReqVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotInformationStatisticsVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.*;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotInformationDO;
import cn.iocoder.yudao.module.system.service.robot.RobotInformationService;
import org.springframework.web.bind.annotation.*;
@ -76,9 +73,9 @@ public class RobotInformationController {
@GetMapping("/page")
@Operation(summary = "获得车辆信息分页")
@PreAuthorize("@ss.hasPermission('robot:information:query')")
public CommonResult<PageResult<RobotInformationRespVO>> getInformationPage(@Valid RobotInformationPageReqVO pageReqVO) {
PageResult<RobotInformationRespVO> pageResult = informationService.getInformationPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, RobotInformationRespVO.class));
public CommonResult<PageResult<RobotInformationPageRespVO>> getInformationPage(@Valid RobotInformationPageReqVO pageReqVO) {
PageResult<RobotInformationPageRespVO> pageResult = informationService.getInformationPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, RobotInformationPageRespVO.class));
}
@GetMapping("/export-excel")
@ -88,10 +85,10 @@ public class RobotInformationController {
public void exportInformationExcel(@Valid RobotInformationPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<RobotInformationRespVO> list = informationService.getInformationPage(pageReqVO).getList();
List<RobotInformationPageRespVO> list = informationService.getInformationPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "车辆信息.xls", "数据", RobotInformationRespVO.class,
BeanUtils.toBean(list, RobotInformationRespVO.class));
ExcelUtils.write(response, "车辆信息.xls", "数据", RobotInformationPageRespVO.class,
BeanUtils.toBean(list, RobotInformationPageRespVO.class));
}
@PostMapping("/statistics")

View File

@ -0,0 +1,55 @@
package cn.iocoder.yudao.module.system.controller.admin.robot.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "管理后台 - 车辆信息 Response VO")
@Data
@ExcelIgnoreUnannotated
public class RobotInformationPageRespVO {
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "21881")
@ExcelProperty("主键ID")
private Long id;
@Schema(description = "车辆类型")
@ExcelProperty("车辆类型")
private String robotModelNumber;
@Schema(description = "AGV编号")
@ExcelProperty("AGV编号")
private String robotNo;
@Schema(description = "上传图片附件", example = "https://www.iocoder.cn")
@ExcelProperty("上传图片附件")
private String url;
@Schema(description = "电量")
@ExcelProperty("电量")
private String electricity;
@Schema(description = "状态0待命、1任务中、2锁定、3离线、4:充电中、5:故障)", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@ExcelProperty("状态0待命、1任务中、2锁定、3离线、4:充电中、5:故障)")
private Integer robotStatus;
@Schema(description = "楼层")
@ExcelProperty("楼层")
public String floor;
@Schema(description = "区域")
@ExcelProperty("区域")
public String area;
@Schema(description = "信息")
@ExcelProperty("信息")
public String msg;
private String macAddress;
/**
* 任务模式0拒收任务1正常
*/
private Integer robotTaskModel;
}

View File

@ -7,12 +7,21 @@ import lombok.Data;
public class RobotInformationStatisticsVO {
@Schema(description = "待命")
private Integer standby;
private Integer standby = 0;
@Schema(description = "任务中")
private Integer inTask;
@Schema(description = "充电中")
private Integer charge;
private Integer inTask = 0;
@Schema(description = "锁定")
private Integer doLock = 0;
@Schema(description = "离线")
private Integer offline;
private Integer offline = 0;
@Schema(description = "充电中")
private Integer charge = 0;
@Schema(description = "故障")
private Integer fault = 0;
}

View File

@ -47,12 +47,6 @@ public interface RobotInformationMapper extends BaseMapperX<RobotInformationDO>
*/
List<RobotInformationDO> queryAllByLimit(RobotInformationDO query);
/**
* 统计车辆任务
* @return
*/
RobotInformationStatisticsVO statisticsInformation();
/**
* 根据机器人编号查询
* @param robotNos

View File

@ -10,20 +10,34 @@ import lombok.Getter;
@AllArgsConstructor
public enum CommandTypeEnum {
MOVE_POSES("MOVE_POSES"),//按规划好的路经移动
MOVE_POSE("MOVE_POSE"),//移动到某个点
JOY_AGV("JOY_AGV"),//遥控AGV运动
JOY_FORK("JOY_FORK"),//遥控货叉上下移动向上移动速度有1到5,向下速度有-5到-1
SHUT_DOWN("SHUT_DOWN"),//关机
RESTART("RESTART"),//重启
STOP("STOP"),//停止
START("START"),//启动
WAIT("WAIT"),//等待
GET_PALLET_TOPIC("GET_PALLET_TOPIC"),//获取托盘位置
MOVE_TO_PALLET_POSE("MOVE_TO_PALLET_POSE"),//让车机移动到取货终点
FORK("FORK"); //控制货叉上下移动
MOVE_POSES("MOVE_POSES","移动"),//按规划好的路经移动
MOVE_POSE("MOVE_POSE","移动"),//移动到某个点
JOY_AGV("JOY_AGV","遥感AGV移动"),//遥控AGV运动
JOY_FORK("JOY_FORK","遥控货叉上下移动"),//遥控货叉上下移动向上移动速度有1到5,向下速度有-5到-1
SHUT_DOWN("SHUT_DOWN","关机"),//关机
RESTART("RESTART","重启"),//重启
STOP("STOP","停止"),//停止
START("START","启动"),//启动
WAIT("WAIT","等待"),//等待
GET_PALLET_TOPIC("GET_PALLET_TOPIC","获取托盘位置"),//获取托盘位置
MOVE_TO_PALLET_POSE("MOVE_TO_PALLET_POSE","移动到取货终点"),//让车机移动到取货终点
FORK("FORK","控制货叉上下移动"); //控制货叉上下移动
/**
* 类型
*/
private final String type;
/**
* 说明
*/
private final String msg;
public static CommandTypeEnum getCommandType(String type) {
for (CommandTypeEnum item : CommandTypeEnum.values()) {
if (item.getType().equals(type)) {
return item;
}
}
return null;
}
}

View File

@ -4,10 +4,7 @@ import java.util.*;
import javax.validation.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotInformationPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotInformationRespVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotInformationSaveReqVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotInformationStatisticsVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.*;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotInformationDO;
/**
@ -53,7 +50,7 @@ public interface RobotInformationService {
* @param pageReqVO 分页查询
* @return 车辆信息分页
*/
PageResult<RobotInformationRespVO> getInformationPage(RobotInformationPageReqVO pageReqVO);
PageResult<RobotInformationPageRespVO> getInformationPage(RobotInformationPageReqVO pageReqVO);
/**
* 统计车辆待命/任务中/离线

View File

@ -2,15 +2,20 @@ package cn.iocoder.yudao.module.system.service.robot;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDataPoseDTO;
import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.*;
import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapDO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotInformationDO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDetailDO;
import cn.iocoder.yudao.module.system.dal.mysql.positionmap.PositionMapMapper;
import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotInformationMapper;
import cn.iocoder.yudao.module.system.enums.robot.RobotTaskModelEnum;
import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotTaskDetailMapper;
import cn.iocoder.yudao.module.system.enums.robot.*;
import cn.iocoder.yudao.module.system.util.redis.RedisUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.v3.oas.annotations.media.Schema;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
@ -38,6 +43,9 @@ public class RobotInformationServiceImpl implements RobotInformationService {
@Resource
private PositionMapMapper positionMapMapper;
@Resource
private RobotTaskDetailMapper taskDetailMapper;
@Resource
private RedisUtil redisUtil;
@ -123,43 +131,128 @@ public class RobotInformationServiceImpl implements RobotInformationService {
}
@Override
public PageResult<RobotInformationRespVO> getInformationPage(RobotInformationPageReqVO pageReqVO) {
public PageResult<RobotInformationPageRespVO> getInformationPage(RobotInformationPageReqVO pageReqVO) {
PageResult<RobotInformationDO> pageResult = informationMapper.selectPage(pageReqVO);
PageResult<RobotInformationRespVO> dataPage = new PageResult<>();
PageResult<RobotInformationPageRespVO> dataPage = new PageResult<>();
dataPage.setTotal(pageResult.getTotal());
List<RobotInformationDO> list = pageResult.getList();
List<RobotInformationRespVO> targetList = BeanUtil.copyToList(list, RobotInformationRespVO.class);
List<RobotInformationPageRespVO> targetList = BeanUtil.copyToList(list, RobotInformationPageRespVO.class);
targetList.stream().forEach(v -> {
setPositionMapList(v);
String electricity = (String)redisUtil.get(RobotTaskChcheConstant.ROBOT_ELECTRICITY + v.getRobotNo());
v.setElectricity(electricity);
setMsgAndRobotStatus(v);
});
dataPage.setList(targetList);
return dataPage;
}
/**
* 设置状态和信息
* @param v
*/
private void setMsgAndRobotStatus(RobotInformationPageRespVO v) {
String pose2dKey = RobotTaskChcheConstant.ROBOT_POSE_BAT +v.getMacAddress();
Object object = redisUtil.get(pose2dKey);
RobotStatusDataPoseDTO robotStatusDataPoseDTO= JSONUtil.toBean((String)object, RobotStatusDataPoseDTO.class);
String robotDoingActionKey = RobotTaskChcheConstant.ROBOT_DOING_ACTION +v.getMacAddress();
Object action = redisUtil.get(robotDoingActionKey);
if (ObjectUtil.isNotEmpty(object) && ObjectUtil.isNotEmpty(robotStatusDataPoseDTO)) {
v.setElectricity(robotStatusDataPoseDTO.getBat_soc());
v.setFloor(robotStatusDataPoseDTO.getFloor());
v.setArea(robotStatusDataPoseDTO.getArea());
}
if (ObjectUtil.isEmpty(object)) {
v.setRobotStatus(3);
v.setMsg("车辆已经离线");
}else if (RobotTaskModelEnum.REJECTION.getType().equals(v.getRobotTaskModel())) {
v.setRobotStatus(2);
v.setMsg("车辆已经锁定");
}else if (RobotStatusEnum.STAND_BY.getType().equals(v.getRobotStatus())) {
//查看机器人最后做的任务是不是充电
RobotTaskDetailDO robotTaskDetailDO = taskDetailMapper.selectOne(new LambdaQueryWrapper<RobotTaskDetailDO>()
.eq(RobotTaskDetailDO::getRobotNo, v.getRobotNo())
.orderByDesc(RobotTaskDetailDO::getCreateTime)
.last("limit 1"));
if (ObjectUtil.isNotEmpty(robotTaskDetailDO)
&& RobotTaskTypeEnum.CHARGE.getType().equals(robotTaskDetailDO.getTaskType())
&& RobotTaskStatusEnum.DOING.getType().equals(robotTaskDetailDO.getTaskStatus())) {
v.setRobotStatus(4);
v.setMsg("车辆正在充电");
}else {
v.setRobotStatus(0);
v.setMsg("车辆正在待命");
}
}else if (RobotStatusEnum.DOING.getType().equals(v.getRobotStatus()) && ObjectUtil.isNotEmpty(action)) {
v.setRobotStatus(1);
CommandTypeEnum commandType = CommandTypeEnum.getCommandType(String.valueOf(action));
if (ObjectUtil.isNotEmpty(commandType)) {
v.setMsg("车辆正在"+commandType.getMsg());
}
} else {
v.setRobotStatus(5);
v.setMsg("车辆发生异常");
}
}
/**
* 统计车辆待命/任务中/离线
* @return
*/
@Override
public RobotInformationStatisticsVO statisticsInformation() {
RobotInformationStatisticsVO info = informationMapper.statisticsInformation();
RobotInformationStatisticsVO info = new RobotInformationStatisticsVO();
RobotInformationDO query = new RobotInformationDO();
List<RobotInformationDO> existRobot = informationMapper.queryAllByLimit(query);
int i = 0;
if (ObjectUtil.isNotEmpty(existRobot)) {
for (RobotInformationDO v : existRobot) {
String electricity = (String)redisUtil.get(RobotTaskChcheConstant.ROBOT_ELECTRICITY + v.getRobotNo());
if (ObjectUtil.isEmpty(electricity)) {
i++;
if (ObjectUtil.isEmpty(existRobot)) {
return info;
}
Integer standby = 0;
Integer inTask = 0;
Integer doLock = 0;
Integer offline = 0;
Integer charge = 0;
Integer fault = 0;
//0待命1任务中2锁定3离线4:充电中5:故障
for (RobotInformationDO v : existRobot) {
String pose2dKey = RobotTaskChcheConstant.ROBOT_POSE_BAT +v.getMacAddress();
Object object = redisUtil.get(pose2dKey);
if (ObjectUtil.isEmpty(object)) {
offline++;
}else if (RobotTaskModelEnum.REJECTION.getType().equals(v.getRobotTaskModel())) {
doLock++;
}else if (RobotStatusEnum.STAND_BY.getType().equals(v.getRobotStatus())) {
//查看机器人最后做的任务是不是充电
RobotTaskDetailDO robotTaskDetailDO = taskDetailMapper.selectOne(new LambdaQueryWrapper<RobotTaskDetailDO>()
.eq(RobotTaskDetailDO::getRobotNo, v.getRobotNo())
.orderByDesc(RobotTaskDetailDO::getCreateTime)
.last("limit 1"));
if (ObjectUtil.isNotEmpty(robotTaskDetailDO)
&& RobotTaskTypeEnum.CHARGE.getType().equals(robotTaskDetailDO.getTaskType())
&& RobotTaskStatusEnum.DOING.getType().equals(robotTaskDetailDO.getTaskStatus())) {
charge++;
}else {
standby++;
}
}else if (RobotStatusEnum.DOING.getType().equals(v.getRobotStatus())) {
inTask++;
} else {
fault++;
}
}
info.setOffline(i);
info.setStandby(standby);
info.setInTask(inTask);
info.setDoLock(doLock);
info.setOffline(offline);
info.setCharge(charge);
info.setFault(fault);
return info;
}

View File

@ -213,13 +213,13 @@ public class RobotTaskAutoMoveServiceImpl implements RobotTaskAutoMoveService {
}
List<WareHouseLocationDO> locationDOS = locationMapper.selectNeedMoveLocation(doingLocationIds);
if (ObjectUtil.isEmpty(locationDOS)) {
log.info("暂无需要自动移库的库位 :{}" ,String.valueOf(robotTaskDetailDO));
log.info("暂无需要自动移库的库位 :{}" ,JSON.toJSONString(robotTaskDetailDO));
continue;
}
boolean enableOrLock = locationDOS.stream().anyMatch(v -> LocationEnableEnum.NO.getType().equals(v.getLocationEnable())
|| LocationLockEnum.NO.getType().equals(v.getLocationLock()));
if (enableOrLock) {
log.info("此库位被锁定或者禁用,无法执行移库 :{}",String.valueOf(locationDOS));
log.info("此库位被锁定或者禁用,无法执行移库 :{}",JSON.toJSONString(locationDOS));
//todo 后期加到告警表里面 方便排查问题
continue;
}

View File

@ -271,18 +271,6 @@
where id = #{id}
</delete>
<select id="statisticsInformation"
resultType="cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotInformationStatisticsVO">
SELECT
(SELECT count(*) from robot_information where robot_status in ('0','3') and deleted = '0' ) AS 'standby',
(SELECT count(*) from robot_task_detail t2 where t2.task_type != 3 and t2.task_status = 1 and deleted = '0') as 'inTask',
(SELECT count(*) from robot_task_detail t2 where t2.task_type = 3 and t2.task_status = 1 and deleted = '0') as 'charge'
from
robot_information
limit 1
</select>
<select id="selectByRobotNos" resultMap="BaseResultMap">
select
<include refid="base_sql"></include>