diff --git a/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/path/dto/PathPosedsDTO.java b/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/path/dto/PathPosedsDTO.java index 10d13a78d..277127a47 100644 --- a/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/path/dto/PathPosedsDTO.java +++ b/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/path/dto/PathPosedsDTO.java @@ -12,8 +12,8 @@ import java.util.List; @NoArgsConstructor @AllArgsConstructor public class PathPosedsDTO { - private String order_id; - private String order_type; + private String orderId; + private String orderType; private String robotNo; private List data; } diff --git a/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/path/dto/PathPosedsDataArgPosedDTO.java b/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/path/dto/PathPosedsDataArgPosedDTO.java index c24e91545..b9420ab2e 100644 --- a/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/path/dto/PathPosedsDataArgPosedDTO.java +++ b/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/path/dto/PathPosedsDataArgPosedDTO.java @@ -12,7 +12,7 @@ import lombok.NoArgsConstructor; @AllArgsConstructor public class PathPosedsDataArgPosedDTO { @Schema(description = "唯一key,导航下发给RCS应用", example = "20863") - private Integer poseId; + private String poseId; private Double x; diff --git a/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/path/dto/PathPosedsDataDTO.java b/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/path/dto/PathPosedsDataDTO.java index b8452f95c..bc37a1559 100644 --- a/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/path/dto/PathPosedsDataDTO.java +++ b/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/path/dto/PathPosedsDataDTO.java @@ -11,5 +11,6 @@ import lombok.NoArgsConstructor; @AllArgsConstructor public class PathPosedsDataDTO { private PathPosedsDataArgDTO arg; - private Integer is_work; + private String commandType; + private Integer isCommandEnd; } diff --git a/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/task/dto/RobotAcceptTaskDTO.java b/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/task/dto/RobotAcceptTaskDTO.java index 0756290dc..38619536f 100644 --- a/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/task/dto/RobotAcceptTaskDTO.java +++ b/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/task/dto/RobotAcceptTaskDTO.java @@ -10,11 +10,11 @@ public class RobotAcceptTaskDTO { /** * 订单id */ - private String order_id; - private String order_type = ""; + private String orderId; + private String orderType = ""; private String topic; //PAUSE(停止)、CONTINUE(继续)、DEFAULT(执行)、CANCEL(取消) - private String execution_type = ExecutionTypeEnum.DEFAULT.getType(); + private String executionType = ExecutionTypeEnum.DEFAULT.getType(); private List data; } diff --git a/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/api/path/PathPlanningApiImpl.java b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/api/path/PathPlanningApiImpl.java index a3623a47f..27d57ac77 100644 --- a/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/api/path/PathPlanningApiImpl.java +++ b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/api/path/PathPlanningApiImpl.java @@ -53,7 +53,6 @@ public class PathPlanningApiImpl implements PathPlanningApi { @Override public void synchronousLineObject(Object obj, String topic) { - log.info("收到请求 :{}", JSON.toJSONString(obj)); try { mqttUtils.pub(topic, JSON.toJSONString(obj)); log.info("同步信息给PP--完成 :{}", JSON.toJSONString(obj)); diff --git a/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/config/MqttFactory.java b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/config/MqttFactory.java index 7a570404c..190cacd8c 100644 --- a/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/config/MqttFactory.java +++ b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/config/MqttFactory.java @@ -145,14 +145,16 @@ public class MqttFactory { return BeanUtils.getBean(RobotWorkStatusServiceImpl.class); case ROBOT_UPDATE_PALLET_HEIGHT: return BeanUtils.getBean(RobotUpdatePalletHeightServiceImpl.class); - case SYNCHRONOUS_ALL_MAP_REQUEST: + case PLANNING_INIT_DATA: return BeanUtils.getBean(PathPlanningInitDataServiceImpl.class); - case TASK_ASSIGNMENT_FEEDBACK: + case PLANNING_DISTRIBUTION_TASK: return BeanUtils.getBean(PathPlanningDistributionTaskServiceImpl.class); - case TASK_ASSIGNMENT_FAIL: + case PLANNING_DISTRIBUTION_FAIL: return BeanUtils.getBean(PathPlanningDistributionFailServiceImpl.class); - case ROBOT_TASK_MOVE: + case PLANNING_MOVE: return BeanUtils.getBean(PathPlanningMoveServiceImpl.class); + case PLANNING_ROUTE_DISPLAY: + return BeanUtils.getBean(PathRouteDisplayPlanningServiceImpl.class); default : return BeanUtils.getBean(RobotTaskStatusServiceImpl.class); } diff --git a/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/enums/DefineSubTopicEnum.java b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/enums/DefineSubTopicEnum.java index 79bc0a92a..4d6f2b6ad 100644 --- a/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/enums/DefineSubTopicEnum.java +++ b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/enums/DefineSubTopicEnum.java @@ -1,7 +1,6 @@ package cn.iododer.yudao.module.mqtt.enums; import lombok.AllArgsConstructor; -import lombok.Data; import lombok.Getter; import java.util.ArrayList; @@ -22,10 +21,11 @@ public enum DefineSubTopicEnum { ROBOT_PATH_STATUS("ROBOT_PATH_STATUS", 2,"导航实时行为上报"), ROBOT_WORK_STATUS("ROBOT_WORK_STATUS", 2,"作业实时行为上报"), ROBOT_UPDATE_PALLET_HEIGHT("UPDATE_PALLET_HEIGHT", 2,"放货后货物高度反馈和取货后货物高度反馈"), - SYNCHRONOUS_ALL_MAP_REQUEST("SYNCHRONOUS_ALL_MAP_REQUEST", 2,"路径规划需要初始数据上报"), - TASK_ASSIGNMENT_FEEDBACK("TASK_ASSIGNMENT_FEEDBACK", 2,"路径规划任务分配上报"), - TASK_ASSIGNMENT_FAIL("TASK_ASSIGNMENT_FAIL", 2,"路径规划失败上报"), - ROBOT_TASK_MOVE ("ROBOT_TASK_MOVE", 2,"路径规划上报实时路径"); + PLANNING_INIT_DATA("SYNCHRONOUS_ALL_MAP_REQUEST", 2,"路径规划需要初始数据上报"), + PLANNING_DISTRIBUTION_TASK("TASK_ASSIGNMENT_FEEDBACK", 2,"路径规划任务分配上报"), + PLANNING_DISTRIBUTION_FAIL("TASK_ASSIGNMENT_FAIL", 2,"路径规划失败上报"), + PLANNING_MOVE("UPDATE_ROUTE_DISPLAY_PLANNING", 2,"车辆即将走的点位"), + PLANNING_ROUTE_DISPLAY("ROBOT_MOVE_POSE_PLANNING", 2,"路径规划上报实时路径"); private final String topic; diff --git a/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/service/PathPlanningMoveServiceImpl.java b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/service/PathPlanningMoveServiceImpl.java index 0bfb8ce31..de36a4384 100644 --- a/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/service/PathPlanningMoveServiceImpl.java +++ b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/service/PathPlanningMoveServiceImpl.java @@ -15,7 +15,7 @@ public class PathPlanningMoveServiceImpl implements MqttService{ @Override public void analysisMessage(String message) { - log.info("收到路径规划的消息"); - pathApi.pathPlanningMove(message); + log.info("收到路径规划规划即将要走的点位的消息 :{}",message); + pathApi.pathPlanningMovePose(message); } } diff --git a/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/service/PathRouteDisplayPlanningServiceImpl.java b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/service/PathRouteDisplayPlanningServiceImpl.java new file mode 100644 index 000000000..d137cdc7a --- /dev/null +++ b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/service/PathRouteDisplayPlanningServiceImpl.java @@ -0,0 +1,21 @@ +package cn.iododer.yudao.module.mqtt.service; + +import cn.iocoder.yudao.module.system.api.path.PathApi; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +@Slf4j +@Service +public class PathRouteDisplayPlanningServiceImpl implements MqttService{ + + @Resource + private PathApi pathApi; + + @Override + public void analysisMessage(String message) { + log.info("收到路径规划的消息 :{}",message); + pathApi.pathPlanningMove(message); + } +} diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/path/PathApi.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/path/PathApi.java index eb079e8d4..ee790e543 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/path/PathApi.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/path/PathApi.java @@ -28,4 +28,8 @@ public interface PathApi { @PostMapping(PREFIX + "/pathPlanningMove") @Operation(summary = "路径规划需要初始化信息") void pathPlanningMove(@RequestParam("message") String message); + + @PostMapping(PREFIX + "/pathPlanningMovePose") + @Operation(summary = "路径规划要走的点位信息") + void pathPlanningMovePose(@RequestParam("message") String message); } diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/vo/PathPlanningMovePoseVO.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/vo/PathPlanningMovePoseVO.java new file mode 100644 index 000000000..5bf96ff11 --- /dev/null +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/vo/PathPlanningMovePoseVO.java @@ -0,0 +1,11 @@ +package cn.iocoder.yudao.module.system.api.robot.vo; + +import lombok.Data; + +import java.util.List; + +@Data +public class PathPlanningMovePoseVO { + private String robotNo; + private List data; +} diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/vo/RobotInformationVO.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/vo/RobotInformationVO.java index 8c4158840..0d93d450f 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/vo/RobotInformationVO.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/vo/RobotInformationVO.java @@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.system.api.robot.vo; import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDataPoseDTO; import lombok.Data; +import java.util.List; + /** * 车机响应信息 */ @@ -24,4 +26,9 @@ public class RobotInformationVO { * 点位信息 */ public RobotStatusDataPoseDTO pose2d; + + /** + * 车辆即将走的点位 + */ + private List data; } diff --git a/yudao-module-system/yudao-module-system-biz/pom.xml b/yudao-module-system/yudao-module-system-biz/pom.xml index 7c02eea96..e8cd5e731 100644 --- a/yudao-module-system/yudao-module-system-biz/pom.xml +++ b/yudao-module-system/yudao-module-system-biz/pom.xml @@ -156,6 +156,22 @@ 2.0 + + com.infiniteautomation + modbus4j + 3.0.3 + + + org.rxtx + rxtx + 2.1.7 + + + org.scream3r + jssc + 2.8.0 + + diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/path/PathApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/path/PathApiImpl.java index 7e31eabcd..3798f5154 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/path/PathApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/path/PathApiImpl.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.system.api.path; import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; +import cn.iocoder.yudao.module.system.config.ratelimiter.SystemRateLimiter; import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapSaveReqVO; import cn.iocoder.yudao.module.system.service.path.PathPlanningService; import cn.iocoder.yudao.module.system.service.robot.RobotTaskService; @@ -43,6 +44,7 @@ public class PathApiImpl implements PathApi { * 发送初始化信息给PP */ @Override + @SystemRateLimiter(time = 10, count = 1, keyArg = "pathInitData",message = "路径规划初始化数据频繁") public void pathInitData() { taskExecutor.execute(() -> { TenantContextHolder.setTenantId(1L); @@ -69,9 +71,6 @@ public class PathApiImpl implements PathApi { taskExecutor.execute(() -> { TenantContextHolder.setTenantId(1L); taskService.assignTasks(message); - if (ObjectUtil.isEmpty(message)) { - return; - } // taskService.ppDistributionTask(message); 废弃了 }); } @@ -82,6 +81,7 @@ public class PathApiImpl implements PathApi { */ @Override public void ppDistributionTaskFail(String message) { + TenantContextHolder.setTenantId(1L); warnMsgService.addWarnMsg(message); } @@ -89,9 +89,20 @@ public class PathApiImpl implements PathApi { public void pathPlanningMove(String message) { log.info("收到路径规划路径的消息 :{}", message); taskExecutor.execute(() -> { + TenantContextHolder.setTenantId(1L); pathPlanningService.sendPosedsToRobot(message); }); } + /** + * 车辆即将走的点位 + * @param message + */ + @Override + public void pathPlanningMovePose(String message) { + TenantContextHolder.setTenantId(1L); + pathPlanningService.pathPlanningMovePose(message); + } + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotGenericsStatusApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotGenericsStatusApiImpl.java index 894927bc0..fac5b520c 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotGenericsStatusApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotGenericsStatusApiImpl.java @@ -4,6 +4,7 @@ import cn.hutool.core.util.ObjectUtil; import cn.hutool.json.JSONUtil; import cn.iocoder.yudao.module.system.api.robot.dto.RobotGenericsDataDTO; import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDataPoseDTO; +import cn.iocoder.yudao.module.system.config.ratelimiter.SystemRateLimiter; import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant; import cn.iocoder.yudao.module.system.util.redis.RedisUtil; import com.alibaba.fastjson.JSON; @@ -25,10 +26,11 @@ public class RobotGenericsStatusApiImpl implements RobotGenericsStatusApi { @Resource private RedisUtil redisUtil; - @Resource@Value("${zn.robot_position_cache_time:600}") + @Resource@Value("${zn.robot_position_cache_time:10}") private Long robotPositionCacheTime; @Override + @SystemRateLimiter(time = 1, count = 20, keyArg = "updateRobotCommonStatus",message = "机器人上报车辆其他信息") public void updateRobotCommonStatus(RobotGenericsDataDTO robotStatusData) { doUpdateRobotCommonStatus(robotStatusData); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotReactiveStatusApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotReactiveStatusApiImpl.java index 77182d170..779bb3b40 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotReactiveStatusApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotReactiveStatusApiImpl.java @@ -37,12 +37,6 @@ public class RobotReactiveStatusApiImpl implements RobotReactiveStatusApi { @Resource private RedisUtil redisUtil; - @Value("${zn.robot_position_cache_time:600}") - private Long robotPositionCacheTime; - - @Value("${zn.robot_error_level_time:30}") - private Long robotErrorLevelTime; - @Resource private RobotWarnMsgService warnMsgService; @@ -59,15 +53,8 @@ public class RobotReactiveStatusApiImpl implements RobotReactiveStatusApi { public void robotReactiveStatus(String message) { TenantContextHolder.setTenantId(1L); RobotReactiveStatusDTO data = JSON.parseObject(message, RobotReactiveStatusDTO.class); - String pose2dKey = RobotTaskChcheConstant.ROBOT_INFORMATION_POSE_BAT_SOC + data.getMac(); - Object object = redisUtil.get(pose2dKey); - RobotStatusDataPoseDTO robotStatusDataPoseDTO = JSONUtil.toBean((String) object, RobotStatusDataPoseDTO.class); - - if (ObjectUtil.isNotEmpty(data.getFloorZone())) { - robotStatusDataPoseDTO.setFloor(data.getFloorZone().getFloor()); - robotStatusDataPoseDTO.setArea(data.getFloorZone().getArea()); - } - redisUtil.set(pose2dKey, JSON.toJSONString(robotStatusDataPoseDTO), robotPositionCacheTime); + String floorAreaKey = RobotTaskChcheConstant.ROBOT_FLOOR_AREA + data.getMac(); + redisUtil.set(floorAreaKey, JSON.toJSONString(data.getFloorZone())); //机器人异常等级 if (ObjectUtil.isEmpty(data.getErrCode())) { @@ -137,8 +124,8 @@ public class RobotReactiveStatusApiImpl implements RobotReactiveStatusApi { msg = warnMsg.getWarnMsg(); } } - redisUtil.set(errorLevelKey, level, robotErrorLevelTime); - redisUtil.set(errorMsgKey, errorMsg, robotErrorLevelTime); + redisUtil.set(errorLevelKey, level); + redisUtil.set(errorMsgKey, errorMsg); warnMsgService.sendWarnMsgToWebsocket(msg); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotStatusApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotStatusApiImpl.java index a4a941bb1..357be6164 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotStatusApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotStatusApiImpl.java @@ -4,11 +4,9 @@ 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.mqtt.api.path.PathPlanningApi; -import cn.iocoder.yudao.module.system.api.robot.dto.RobotPoseStatusDTO; -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.api.robot.dto.RobotStatusDataPoseDTO; +import cn.iocoder.yudao.module.system.api.robot.dto.*; import cn.iocoder.yudao.module.system.api.robot.vo.RobotInformationVO; +import cn.iocoder.yudao.module.system.config.ratelimiter.SystemRateLimiter; import cn.iocoder.yudao.module.system.constant.path.PathPlanningTopicConstant; import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant; import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotWarnCodeMappingDO; @@ -45,7 +43,7 @@ public class RobotStatusApiImpl implements RobotStatusApi { @Autowired private RobotInformationService robotInformationService; - @Value("${zn.robot_position_cache_time:600}") + @Value("${zn.robot_position_cache_time:10}") private Long robotPositionCacheTime; @Resource @@ -64,10 +62,9 @@ public class RobotStatusApiImpl implements RobotStatusApi { * @return */ @Override + @SystemRateLimiter(time = 1, count = 150, keyArg = "robotStatusUpdate",message = "机器人上报点位超过限流") public void robotStatusUpdate(RobotPoseStatusDTO robotStatusDataDTO) { - taskExecutor.execute(()->{ - updateRobotPosed(robotStatusDataDTO); - }); + updateRobotPosed(robotStatusDataDTO); } /** @@ -80,6 +77,9 @@ public class RobotStatusApiImpl implements RobotStatusApi { log.info("机器人上报的信息不全 :{}", JSON.toJSONString(robotStatusDataDTO)); return; } + String floorAreaKey = RobotTaskChcheConstant.ROBOT_FLOOR_AREA + robotStatusDataDTO.getMac(); + Object floorAreaObject = redisUtil.get(floorAreaKey); + FloorZoneDTO floorZoneDTO = JSONUtil.toBean((String) floorAreaObject, FloorZoneDTO.class); String robotNo = robotInformationService.getRobotNoByMac(robotStatusDataDTO.getMac()); String pose2dKey = RobotTaskChcheConstant.ROBOT_INFORMATION_POSE_BAT_SOC + robotStatusDataDTO.getMac(); Object object = redisUtil.get(pose2dKey); @@ -91,8 +91,9 @@ public class RobotStatusApiImpl implements RobotStatusApi { robotStatusDataPoseDTO.setYaw(robotStatusDataDTO.getPose2d().getYaw()); } robotStatusDataPoseDTO.setRobotNo(robotNo); + robotStatusDataPoseDTO.setFloor(floorZoneDTO.getFloor()); + robotStatusDataPoseDTO.setArea(floorZoneDTO.getArea()); redisUtil.set(pose2dKey, JSON.toJSONString(robotStatusDataPoseDTO), robotPositionCacheTime); - pathPlanningApi.synchronousLineObject(robotStatusDataPoseDTO, PathPlanningTopicConstant.AGV_POSE); //机器人身上是否有货 String taskStatusKey = RobotTaskChcheConstant.ROBOT_TASK_STATUS + robotStatusDataDTO.getMac(); @@ -107,8 +108,16 @@ public class RobotStatusApiImpl implements RobotStatusApi { robotInformationVO = robotInformationService.getRobotByRedis(robotStatusDataDTO.getMac()); } robotInformationVO.setPose2d(robotStatusDataPoseDTO); + // 合并请求 - 这里接受到的数据都丢给 RequestProcessor - 再整合数据通过WebSocket丢给前端 - processor.handleRequest(robotStatusDataPoseDTO.getFloor() + "_" + robotStatusDataPoseDTO.getArea(), + processor.handleRequest(floorZoneDTO.getFloor() + "_" + floorZoneDTO.getArea(), robotStatusDataDTO.getMac(), JSONUtil.toJsonStr(robotInformationVO)); + sendToPP(robotStatusDataPoseDTO); + } + + private void sendToPP(RobotStatusDataPoseDTO robotStatusDataPoseDTO) { + taskExecutor.execute(()->{ + pathPlanningApi.synchronousLineObject(robotStatusDataPoseDTO, PathPlanningTopicConstant.AGV_POSE); + }); } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotTaskStatusApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotTaskStatusApiImpl.java index 331d8f91d..82cb07491 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotTaskStatusApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotTaskStatusApiImpl.java @@ -23,13 +23,16 @@ import cn.iocoder.yudao.module.system.enums.common.ZeroOneEnum; import cn.iocoder.yudao.module.system.enums.path.PathIsReachEnum; import cn.iocoder.yudao.module.system.enums.path.PathTaskTypeEnum; import cn.iocoder.yudao.module.system.enums.robot.*; +import cn.iocoder.yudao.module.system.enums.robot.actionlog.ActionStatusEnum; import cn.iocoder.yudao.module.system.enums.robot.charge.ChargeTaskStatusEnum; import cn.iocoder.yudao.module.system.enums.robot.task.RobotStatusCodeEnum; import cn.iocoder.yudao.module.system.enums.robot.task.RobotTaskStageEnum; import cn.iocoder.yudao.module.system.enums.wait.WaitStatusEnum; +import cn.iocoder.yudao.module.system.service.information.DeviceInformationService; import cn.iocoder.yudao.module.system.service.path.PathPlanningService; import cn.iocoder.yudao.module.system.service.robot.RobotInformationService; import cn.iocoder.yudao.module.system.service.robot.RobotTaskDetailService; +import cn.iocoder.yudao.module.system.service.robot.RobotTaskService; import cn.iocoder.yudao.module.system.service.robot.RobotWarnMsgService; import cn.iocoder.yudao.module.system.service.wait.MoveToWaitService; import cn.iocoder.yudao.module.system.util.redis.RedisUtil; @@ -46,8 +49,6 @@ import javax.annotation.Resource; import java.time.LocalDateTime; import java.util.List; -import static com.baomidou.mybatisplus.core.toolkit.IdWorker.getId; - @Slf4j @RestController // 提供 RESTful API 接口,给 Feign 调用 @Validated @@ -87,9 +88,6 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi { @Resource private CommonApi commonApi; - @Resource - public WebSocketSenderApi webSocketSenderApi; - @Resource private RobotTaskDetailService taskDetailService; @@ -99,15 +97,15 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi { @Resource private RobotWarnMsgService warnMsgService; - @Resource - private DeviceInformationMapper deviceInformationMapper; - @Resource private MoveToWaitService moveToWaitService; @Resource private PathPlanningService pathPlanningService; + @Resource + private DeviceInformationService deviceInformationService; + @Value("${zn.robot_doing_action.doing_action_cache_time:2*24*60*60}") private Long doingActionCacheTime; @@ -155,8 +153,20 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi { taskDoing(robotCompleteTaskDTO, robotDoingActionKey); } + if ((PathTaskTypeEnum.AUTO_CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType()) + || PathTaskTypeEnum.CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType())) + && ObjectUtil.isNotEmpty(robotCompleteTaskDTO.getCommandStatus()) + && CommandTypeEnum.MOVE_POSES.getType().equals(robotCompleteTaskDTO.getCommandStatus().getCommandType()) + && RobotExecutionStateConstant.DONE.equals(robotCompleteTaskDTO.getCommandStatus().getExecutionState())) { + log.info("充电任务准备让充电设备自动伸出 :{}",robotCompleteTaskDTO.getOrderId()); + RobotChargeLogDO robotChargeLog = chargeLogMapper.selectById(robotCompleteTaskDTO.getOrderId()); + deviceInformationService.chargeDeviceExtend(robotChargeLog.getDeviceNo()); + } + sendStartDoActionToPP(robotCompleteTaskDTO.getCommandStatus(), robotCompleteTaskDTO.getMac(), String.valueOf(robotCompleteTaskDTO.getOrderId())); + + taskDetailActionLogMapper.updateActionStatus(robotCompleteTaskDTO.getOrderId(), ActionStatusEnum.DOING.getType()); } /** @@ -207,6 +217,7 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi { .build(); chargeLogMapper.updateById(build); } + taskDetailActionLogMapper.updateActionStatus(robotCompleteTaskDTO.getOrderId(), ActionStatusEnum.DONE.getType()); } @@ -232,7 +243,8 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi { */ @Transactional(rollbackFor = Exception.class) public void closeTask(RobotCompleteTaskDTO robotCompleteTaskDTO) { - PPCloseOrder(robotCompleteTaskDTO); + /*PPCloseOrder(robotCompleteTaskDTO); + taskService.closeTaskDetail(robotCompleteTaskDTO.getOrderId().toString(),robotCompleteTaskDTO.getMac());*/ String robotNo = robotInformationService.getRobotNoByMac(robotCompleteTaskDTO.getMac()); //先不释放库位状态 @@ -268,7 +280,7 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi { .warnCode(robotCompleteTaskDTO.getStatusCode()) .robotNo(robotNo) .warnType(RobotWarnType.ROBOT_WARN.getType()) - .warnMsg(robotNo +"_"+robotCompleteTaskDTO.getMessage()) + .warnMsg(robotNo + "_" + robotCompleteTaskDTO.getMessage()) .warnSolve(robotCompleteTaskDTO.getSolution()) .build(); warnMsgMapper.insert(warnMsg); @@ -325,6 +337,7 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi { RobotTaskDetailDO detailDO = new RobotTaskDetailDO(); detailDO.setId(robotCompleteTaskDTO.getOrderId()); detailDO.setEndTime(LocalDateTime.now()); + detailDO.setTaskStage(RobotTaskStageEnum.DONE.getType()); detailDO.setTaskStatus(RobotTaskDetailStatusEnum.DONE.getType()); robotTaskDetailMapper.updateRobotDetailById(detailDO); //更新任务状态 @@ -349,7 +362,7 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi { && ZeroOneEnum.ONE.getType().equals(robotTaskDetailDO.getNeedLock()))) { robotInformationDO.setRobotTaskModel(RobotTaskModelEnum.REJECTION.getType()); } - robotInformationMapper.updateBatch(robotInformationDO); + robotInformationMapper.updateById(robotInformationDO); //同步任务完成给PP pathPlanningService.updateBehavior(String.valueOf(robotCompleteTaskDTO.getOrderId()), robotTaskDetailDO.getRobotNo() , "", PathIsReachEnum.END_WORK.getType()); @@ -430,7 +443,7 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi { logOne.setTaskDetailId(robotCompleteTaskDTO.getOrderId()); taskDetailActionLogMapper.insert(logOne); redisUtil.set(robotDoingActionKey, logOne.getActionMsg(), doingActionCacheTime); - robotTaskDetailMapper.updateBatch(robotTaskDetailDO); + robotTaskDetailMapper.updateById(robotTaskDetailDO); } public void freeLocation(Boolean isTake, Long taskDetailId) { diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/config/aop/SystemRateLimiterAspect.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/config/aop/SystemRateLimiterAspect.java new file mode 100644 index 000000000..43385c6e4 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/config/aop/SystemRateLimiterAspect.java @@ -0,0 +1,85 @@ +package cn.iocoder.yudao.module.system.config.aop; + +import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.module.system.config.ratelimiter.SystemRateLimiter; +import cn.iocoder.yudao.module.system.util.redis.RedisUtil; +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.lang.reflect.Method; + +/** + * 拦截声明了 {@link SystemRateLimiter} 注解的方法,实现限流操作 + * + * @author 芋道源码 + */ +@Aspect +@Component +@Slf4j +public class SystemRateLimiterAspect { + private static final Logger logger = LoggerFactory.getLogger(SystemRateLimiterAspect.class); + + @Resource + private RedisUtil redisUtil; + + @Value("${zn.open_rate_limiter:false}") + private Boolean openRateLimiter; + + @Pointcut("@annotation(cn.iocoder.yudao.module.system.config.ratelimiter.SystemRateLimiter)") + public void serviceLimit() { + + } + + @Around("serviceLimit()") + public Object around(ProceedingJoinPoint joinPoint) throws Throwable { + if (!openRateLimiter) { + return joinPoint.proceed(); + } + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + Method method = signature.getMethod(); + SystemRateLimiter systemRateLimiter = method.getAnnotation(SystemRateLimiter.class); + String key = systemRateLimiter.keyArg(); + int time = systemRateLimiter.time(); + // 获取redis的value + Integer maxTimes = null; + Object value = redisUtil.get(key); + if (value != null) { + maxTimes = (Integer) value; + } + + Object obj = null; + + if (maxTimes == null) { + // 如果redis中没有该ip对应的时间则表示第一次调用,保存key到redis + redisUtil.set(key, 1, time); + //这个方法用于执行原来的方法或继续原来的控制流程。 + obj = joinPoint.proceed(); + } else if (maxTimes < systemRateLimiter.count()) { + // 如果redis中的时间比注解上的时间小则表示可以允许访问,这是修改redis的value时间 + redisUtil.set(key, maxTimes + 1, time); + //这个方法用于执行原来的方法或继续原来的控制流程。 + obj = joinPoint.proceed(); + } else { + // 请求过于频繁 + logger.info("请求过于频繁 :{}", key); + } + return obj; + } + + + +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/config/ratelimiter/SystemRateLimiter.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/config/ratelimiter/SystemRateLimiter.java new file mode 100644 index 000000000..d72127958 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/config/ratelimiter/SystemRateLimiter.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.system.config.ratelimiter; + +import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 限流注解 + * + * @author 芋道源码 + */ +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface SystemRateLimiter { + /** + * 限流的时间,默认为 1 秒 + */ + int time() default 1; + + /** + * 限流次数 + */ + int count() default 100; + + /** + * 提示信息,请求过快的提示 + * + * @see GlobalErrorCodeConstants#TOO_MANY_REQUESTS + */ + String message() default ""; // 为空时,使用 TOO_MANY_REQUESTS 错误提示 + + /** + * 使用的 Key 参数 + */ + String keyArg() default ""; +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/constant/robot/RobotTaskChcheConstant.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/constant/robot/RobotTaskChcheConstant.java index ddc5feefd..3bd6671a8 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/constant/robot/RobotTaskChcheConstant.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/constant/robot/RobotTaskChcheConstant.java @@ -11,6 +11,9 @@ public class RobotTaskChcheConstant { //机器人点位和电量 (拼接的是mac地址) public static String ROBOT_INFORMATION_POSE_BAT_SOC = "robot:information:pose:bat:soc"; + //机器人楼层和区域 (拼接的是mac地址) + public static String ROBOT_FLOOR_AREA = "robot:floor:area"; + //机器人mac地址和机器人编号映射(通过mac地址。查询机器人编号) (拼接的是mac地址) public static String ROBOT_GET_ROBOTNO_BY_MAC = "robot:information:getRobotNo:ByMac"; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/constant/robot/RobotTopicConstant.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/constant/robot/RobotTopicConstant.java index f351bf16d..d5c5a970c 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/constant/robot/RobotTopicConstant.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/constant/robot/RobotTopicConstant.java @@ -11,7 +11,7 @@ public class RobotTopicConstant { /** * 下发让车子移动 */ - public static String ROBOT_TASK_MOVE_TOPIC = "ROBOT_TASK_MOVE"; + public static String ROBOT_TASK_MOVE_TOPIC = "ROBOT_TASK_MOVE_"; /** *RCS发送心跳给车机 */ @@ -19,5 +19,5 @@ public class RobotTopicConstant { /** * 让机器人同步告警码值映射的topic (拼接mac地址) */ - public static String UPDATE_ERROR_TOPIC = "UPDATE_ERROR"; + public static String UPDATE_ERROR_TOPIC = "UPDATE_ERROR_"; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/constant/webSocket/WebSocketConstant.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/constant/webSocket/WebSocketConstant.java index 69c1eef59..9d82541e1 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/constant/webSocket/WebSocketConstant.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/constant/webSocket/WebSocketConstant.java @@ -4,7 +4,7 @@ public class WebSocketConstant { //webSocket推送给前端的告警信息key public static String AGV_WARN = "agv_warn"; /** - * webSocket推送给站内信息key + * webSocket推送车机要走的点位id */ - public static String STATION_WARN = "station_warn"; + public static String PLANNING_MOVE_POSE = "planning_move_pose"; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/information/vo/DeviceInformationPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/information/vo/DeviceInformationPageReqVO.java index 67e9ca12f..d64fd51e9 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/information/vo/DeviceInformationPageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/information/vo/DeviceInformationPageReqVO.java @@ -80,4 +80,13 @@ public class DeviceInformationPageReqVO extends PageParam { @Schema(description = "设备专有属性(1:自动充电类型充电桩、2:手动充电类型充电桩)") private Integer deviceAttribute; + @Schema(description = "设备IP") + private String deviceIp; + + @Schema(description = "端口") + private String devicePort; + + @Schema(description = "最后使用者") + private String lastUser; + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/information/vo/DeviceInformationRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/information/vo/DeviceInformationRespVO.java index 5c66f21f0..265291dd3 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/information/vo/DeviceInformationRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/information/vo/DeviceInformationRespVO.java @@ -108,4 +108,16 @@ public class DeviceInformationRespVO { @ExcelProperty("地图所在区域") public String area; + @Schema(description = "设备IP") + @ExcelProperty("设备IP") + private String deviceIp; + + @Schema(description = "端口") + @ExcelProperty("端口") + private String devicePort; + + @Schema(description = "最后使用者") + @ExcelProperty("最后使用者") + private String lastUser; + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/information/vo/DeviceInformationSaveReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/information/vo/DeviceInformationSaveReqVO.java index 899c1fc48..523268ad6 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/information/vo/DeviceInformationSaveReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/information/vo/DeviceInformationSaveReqVO.java @@ -76,6 +76,13 @@ public class DeviceInformationSaveReqVO { @Schema(description = "设备专有属性(1:自动充电类型充电桩、2:手动充电类型充电桩)") private Integer deviceAttribute; + @Schema(description = "设备IP") + private String deviceIp; + @Schema(description = "端口") + private String devicePort; + + @Schema(description = "最后使用者") + private String lastUser; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/task/TaskAssignDTO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/task/TaskAssignDTO.java index 7882fa85e..f5be27fd4 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/task/TaskAssignDTO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/task/TaskAssignDTO.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.system.controller.admin.robot.task; +import cn.iocoder.yudao.module.system.enums.path.PathTaskTypeEnum; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; @@ -18,8 +19,33 @@ public class TaskAssignDTO { private Long orderId; @Schema(description = "任务类型(TAKE_RELEASE、CHARGE、MOVE、TAKE、RELEASE、AUTO_CHARGE)") - private String type; + private String orderType; @Schema(description = "AGV编号") private String robotNo; + + /** + * 获取机器人要做的任务描述 + * @return + */ + public String getRobotActionMsg() { + if (PathTaskTypeEnum.TAKE_RELEASE.getType().equals(orderType)) { + return "机器人分配到取放货任务"; + }if (PathTaskTypeEnum.CHARGE.getType().equals(orderType)) { + return "机器人分配到充电任务"; + }if (PathTaskTypeEnum.MOVE.getType().equals(orderType)) { + return "机器人分配到移动任务"; + }if (PathTaskTypeEnum.MOVE_TO_WAIT.getType().equals(orderType)) { + return "机器人分配移动到等待点的任务"; + }if (PathTaskTypeEnum.MOVE_TO_WAIT_STOP.getType().equals(orderType)) { + return "机器人分配停车任务"; + }if (PathTaskTypeEnum.TAKE.getType().equals(orderType)) { + return "机器人分配到仅取货任务"; + }if (PathTaskTypeEnum.RELEASE.getType().equals(orderType)) { + return "机器人分配到仅放货任务"; + }if (PathTaskTypeEnum.AUTO_CHARGE.getType().equals(orderType)) { + return "机器人分配到自动充电任务"; + } + return "未知任务"; + } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotTaskSaveReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotTaskSaveReqVO.java index 90d677356..bc9f7d549 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotTaskSaveReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotTaskSaveReqVO.java @@ -22,6 +22,7 @@ public class RobotTaskSaveReqVO { private List taskDetailList; @Schema(description = "物料信息") + @Size(min = 0, max = 100, message = "物料信息输入的数据长度超过限制") private String skuInfo; @Schema(description = "物料批次号") @@ -34,6 +35,7 @@ public class RobotTaskSaveReqVO { private Long priority; @Schema(description = "其他信息") + @Size(min = 0, max = 100, message = "其他信息输入的数据长度超过限制") private String otherMsg; @Schema(description = "循环(0:不循环、1:循环)") diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/information/DeviceInformationDO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/information/DeviceInformationDO.java index b2f5c16c5..df185bc94 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/information/DeviceInformationDO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/information/DeviceInformationDO.java @@ -120,4 +120,19 @@ public class DeviceInformationDO extends BaseDO { */ private Integer deviceAttribute; + /** + * 设备IP + */ + private String deviceIp; + + /** + * 端口 + */ + private String devicePort; + + /** + * 最后使用者 + */ + private String lastUser; + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/log/RobotTaskDetailActionLogMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/log/RobotTaskDetailActionLogMapper.java index 13572d30c..bb48170ff 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/log/RobotTaskDetailActionLogMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/log/RobotTaskDetailActionLogMapper.java @@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.module.system.controller.admin.log.vo.RobotTaskDetailActionLogPageReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.log.RobotTaskDetailActionLogDO; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; /** * 车辆动作记录 Mapper @@ -27,4 +28,11 @@ public interface RobotTaskDetailActionLogMapper extends BaseMapperX { * @return */ List getLastTaskGroupByRobotNo(); + + /** + * 设置状态为完成 + * @param ids + */ + void updateDoneByIds(@Param("ids") List ids); } \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/robot/RobotTaskMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/robot/RobotTaskMapper.java index 6e5466881..b195f3e89 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/robot/RobotTaskMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/robot/RobotTaskMapper.java @@ -73,4 +73,10 @@ public interface RobotTaskMapper extends BaseMapperX { */ IPage selectLogPageList(@Param("mpPage") IPage mpPage, @Param("pageReqVO") RobotTaskDetailLogVO pageReqVO); + + /** + * 更新任务完成 + * @param ids + */ + void updateDoneByIds(@Param("ids") List ids); } \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/enums/robot/actionlog/ActionStatusEnum.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/enums/robot/actionlog/ActionStatusEnum.java new file mode 100644 index 000000000..38c393455 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/enums/robot/actionlog/ActionStatusEnum.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.system.enums.robot.actionlog; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum ActionStatusEnum { + + UN_DO(0,"未开始"), + DOING(1,"正在进行"), + DONE(2,"完成"); + /** + * 类型 + */ + private final Integer type; + /** + * 说明 + */ + private final String msg; +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/information/DeviceInformationService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/information/DeviceInformationService.java index 52cbc2345..ca3d2fbca 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/information/DeviceInformationService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/information/DeviceInformationService.java @@ -118,4 +118,16 @@ public interface DeviceInformationService extends IService * @return */ List getDeviceInfoBindByMapId(Long positionMapId); + + /** + * 充电任务,让设备伸出 + * @param deviceNo + */ + void chargeDeviceExtend(String deviceNo); + + /** + * 充电设备, 缩 + * @param deviceNo + */ + void chargeDeviceShrink(String deviceNo); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/information/DeviceInformationServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/information/DeviceInformationServiceImpl.java index ec66cdfd6..ae2457be5 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/information/DeviceInformationServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/information/DeviceInformationServiceImpl.java @@ -18,14 +18,22 @@ import cn.iocoder.yudao.module.system.dal.dataobject.information.DeviceInformati import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapDO; import cn.iocoder.yudao.module.system.dal.mysql.information.DeviceInformationMapper; import cn.iocoder.yudao.module.system.dal.mysql.positionmap.PositionMapMapper; +import cn.iocoder.yudao.module.system.enums.device.DeviceAttributeEnum; import cn.iocoder.yudao.module.system.enums.device.DeviceStatusEnum; +import cn.iocoder.yudao.module.system.enums.device.DeviceTypeEnum; import cn.iocoder.yudao.module.system.enums.device.PictureConfigEnum; import cn.iocoder.yudao.module.system.service.dict.DictDataService; import cn.iocoder.yudao.module.system.service.log.UserOperationLogService; +import cn.iocoder.yudao.module.system.service.robot.RobotWarnMsgService; +import cn.iocoder.yudao.module.system.util.modbus3.ModbusUtils; import cn.iocoder.yudao.module.system.util.redis.RedisUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.serotonin.modbus4j.ModbusMaster; +import com.serotonin.modbus4j.exception.ModbusInitException; +import com.serotonin.modbus4j.exception.ModbusTransportException; import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -67,6 +75,9 @@ public class DeviceInformationServiceImpl extends ServiceImpl() + .eq(DeviceInformationDO::getDeviceNo, deviceNo)); + if (ObjectUtil.isEmpty(deviceInformationDO)) { + log.info("查不到此充电设备 :{}", deviceNo); + return; + } + if (DeviceAttributeEnum.HAND_MOVEMENT.getType().equals(deviceInformationDO.getDeviceAttribute())) { + log.info("手动充电设备,不需要伸出 :{}", deviceNo); + return; + } + if (!DeviceTypeEnum.CHARGING_STATION.getType().equals(deviceInformationDO.getDeviceType())) { + log.info("非充电设备,不能伸出 :{}", deviceNo); + return; + } + if (ObjectUtil.isEmpty(deviceInformationDO.getDeviceIp()) || ObjectUtil.isEmpty(deviceInformationDO.getDevicePort())) { + log.info("没有设备IP、端口不能伸出 :{}", deviceNo); + warnMsgService.addWarnMsg(deviceNo + " 没有设备IP和端口"); + return; + } + log.info("设备伸出 :{}",deviceNo); + extend(deviceInformationDO.getDeviceIp(), Integer.parseInt(deviceInformationDO.getDevicePort()), deviceNo); + } + + /** + * 充电任务,缩 + * @param deviceNo + */ + @Override + @Async + public void chargeDeviceShrink(String deviceNo) { + DeviceInformationDO deviceInformationDO = informationMapper.selectOne(new LambdaQueryWrapperX() + .eq(DeviceInformationDO::getDeviceNo, deviceNo)); + if (DeviceAttributeEnum.HAND_MOVEMENT.getType().equals(deviceInformationDO.getDeviceAttribute())) { + log.info("手动充电设备,不需要缩 :{}", deviceNo); + return; + } + if (!DeviceTypeEnum.CHARGING_STATION.getType().equals(deviceInformationDO.getDeviceType())) { + log.info("非充电设备,不能缩回 :{}", deviceNo); + return; + } + if (ObjectUtil.isEmpty(deviceInformationDO.getDeviceIp()) || ObjectUtil.isEmpty(deviceInformationDO.getDevicePort())) { + log.info("没有设备IP、端口不能缩回 :{}", deviceNo); + return; + } + log.info("设备缩回 :{}",deviceNo); + shrink(deviceInformationDO.getDeviceIp(), Integer.parseInt(deviceInformationDO.getDevicePort()), deviceNo); + } + + public void shrink(String ip, int port, String deviceNo) { + boolean success = true; + short[] shrinkArr = {0}; + for (int i = 0; i < 3; i++) { + try { + ModbusMaster asciiMaster = ModbusUtils.getMaster(ip, port); + ModbusUtils.writeHoldingRegisters(asciiMaster, 1, 0, shrinkArr); + } catch (ModbusInitException | ModbusTransportException e) { + log.info("充电设备缩回时,出现异常 :{}", ip); + warnMsgService.addWarnMsg(deviceNo + " 充电设备缩回失败"); + success = false; + } + + if (success) { + return; + } + } + } + + /** + * 控制设备伸缩 + * @param ip + * @param port + */ + public void extend(String ip, int port, String deviceNo) { + boolean success = true; + short[] extendArr = {1}; + short[] shrinkArr = {0}; + for (int i = 0; i < 3; i++) { + try { + ModbusMaster asciiMaster = ModbusUtils.getMaster(ip, port); + ModbusUtils.writeHoldingRegisters(asciiMaster, 1, 0, shrinkArr); + Thread.sleep(2500); + ModbusUtils.writeHoldingRegisters(asciiMaster, 1, 0, extendArr); + } catch (ModbusInitException | ModbusTransportException | InterruptedException e) { + log.info("充电设备伸出时,出现异常 :{}", ip); + warnMsgService.addWarnMsg(deviceNo + " 充电设备伸出失败"); + success = false; + } + + if (success) { + return; + } + } + } + @Override public void mapBindDeviceInfo(MapBindDeviceInfoDTO dto) { DeviceInformationDO deviceInformationDO = informationMapper.selectById(dto.getDeviceInfoId()); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/log/UserOperationLogServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/log/UserOperationLogServiceImpl.java index 3882d8b8e..38f09f714 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/log/UserOperationLogServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/log/UserOperationLogServiceImpl.java @@ -33,6 +33,9 @@ public class UserOperationLogServiceImpl implements UserOperationLogService { @Override public Long createUserOperationLog(UserOperationLogSaveReqVO createReqVO) { // 插入 + if (createReqVO.getOperateAction().length() > 95) { + createReqVO.setOperateAction(createReqVO.getOperateAction().substring(0,95)); + } UserOperationLogDO userOperationLog = BeanUtils.toBean(createReqVO, UserOperationLogDO.class); userOperationLogMapper.insert(userOperationLog); // 返回 diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/path/PathPlanningService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/path/PathPlanningService.java index f1aca0a5d..6f32a49f1 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/path/PathPlanningService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/path/PathPlanningService.java @@ -38,4 +38,10 @@ public interface PathPlanningService { * @param type */ void updateBehavior(String orderId, String robotNo, String s, String type); + + /** + * 车辆即将走的点位 + * @param message + */ + void pathPlanningMovePose(String message); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/path/PathPlanningServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/path/PathPlanningServiceImpl.java index 1707ac0ec..6d5ae9bd1 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/path/PathPlanningServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/path/PathPlanningServiceImpl.java @@ -1,13 +1,23 @@ package cn.iocoder.yudao.module.system.service.path; import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONUtil; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.infra.api.websocket.WebSocketSenderApi; import cn.iocoder.yudao.module.mqtt.api.common.CommonApi; import cn.iocoder.yudao.module.mqtt.api.path.PathPlanningApi; import cn.iocoder.yudao.module.mqtt.api.path.dto.*; import cn.iocoder.yudao.module.mqtt.api.path.task.TaskPathPlanningDTO; +import cn.iocoder.yudao.module.system.api.robot.RequestProcessor; +import cn.iocoder.yudao.module.system.api.robot.dto.FloorZoneDTO; +import cn.iocoder.yudao.module.system.api.robot.dto.RobotPoseStatusDTO; +import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDataPoseDTO; +import cn.iocoder.yudao.module.system.api.robot.vo.PathPlanningMovePoseVO; +import cn.iocoder.yudao.module.system.api.robot.vo.RobotInformationVO; import cn.iocoder.yudao.module.system.constant.path.PathPlanningTopicConstant; +import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant; import cn.iocoder.yudao.module.system.constant.robot.RobotTopicConstant; +import cn.iocoder.yudao.module.system.constant.webSocket.WebSocketConstant; import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapItemSaveReqVO; import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapLineSaveReqVO; import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapSaveReqVO; @@ -22,6 +32,7 @@ import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotInformationMapper; import cn.iocoder.yudao.module.system.enums.line.DirectionEnum; import cn.iocoder.yudao.module.system.enums.path.PathTypeEnum; import cn.iocoder.yudao.module.system.service.robot.RobotInformationService; +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; @@ -69,6 +80,15 @@ public class PathPlanningServiceImpl implements PathPlanningService { @Resource private CommonApi commonApi; + @Resource + private RequestProcessor processor; + + @Resource + private RedisUtil redisUtil; + + @Resource + public WebSocketSenderApi webSocketSenderApi; + /** * 同步ware_position_map_line的点位信息 */ @@ -409,6 +429,21 @@ public class PathPlanningServiceImpl implements PathPlanningService { commonApi.commonMethod(build, PathPlanningTopicConstant.UPDATE_BEHAVIOR); } + /** + * 车辆即将走的点位 + * @param message + */ + @Override + public void pathPlanningMovePose(String message) { + PathPlanningMovePoseVO robotStatusData = JSON.parseObject(message, PathPlanningMovePoseVO.class); + String mac = robotInformationService.getMacByRobotNo(robotStatusData.getRobotNo()); + String floorAreaKey = RobotTaskChcheConstant.ROBOT_FLOOR_AREA + mac; + Object floorAreaObject = redisUtil.get(floorAreaKey); + FloorZoneDTO floorZoneDTO = JSONUtil.toBean((String) floorAreaObject, FloorZoneDTO.class); + webSocketSenderApi.sendObject(floorZoneDTO.getFloor() + "_" + floorZoneDTO.getArea(), + WebSocketConstant.PLANNING_MOVE_POSE, message); + } + public PositionMapLineDTO setPositionMapLineDTOData(PositionMapLineDTO positionMapLineDO) { PositionMapLineDTO build = PositionMapLineDTO.builder() .id(positionMapLineDO.getId()) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotInformationServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotInformationServiceImpl.java index 26e15d6c9..0c9402a80 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotInformationServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotInformationServiceImpl.java @@ -12,6 +12,7 @@ import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; import cn.iocoder.yudao.module.mqtt.api.common.CommonApi; import cn.iocoder.yudao.module.mqtt.api.task.dto.RobotRcsHeartBeatDTO; import cn.iocoder.yudao.module.system.api.robot.RequestProcessor; +import cn.iocoder.yudao.module.system.api.robot.dto.FloorZoneDTO; import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDTO; import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDataPoseDTO; import cn.iocoder.yudao.module.system.api.robot.vo.RobotInformationVO; @@ -205,10 +206,13 @@ public class RobotInformationServiceImpl extends ServiceImpl { * @param message */ void assignTasks(String message); + + /** + * 发送关闭任务 + * @param id + * @param mac + */ + void closeTaskDetail(String id, String mac); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotTaskServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotTaskServiceImpl.java index 627c96467..6375478ee 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotTaskServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotTaskServiceImpl.java @@ -27,6 +27,7 @@ import cn.iocoder.yudao.module.system.dal.dataobject.housearea.HouseAreaDO; import cn.iocoder.yudao.module.system.dal.dataobject.houselane.WareHouseLaneDO; import cn.iocoder.yudao.module.system.dal.dataobject.houselocation.WareHouseLocationDO; import cn.iocoder.yudao.module.system.dal.dataobject.information.DeviceInformationDO; +import cn.iocoder.yudao.module.system.dal.dataobject.log.RobotTaskDetailActionLogDO; import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotChargeLogDO; import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotInformationDO; import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDO; @@ -36,6 +37,7 @@ import cn.iocoder.yudao.module.system.dal.mysql.housearea.HouseAreaMapper; import cn.iocoder.yudao.module.system.dal.mysql.houselane.WareHouseLaneMapper; import cn.iocoder.yudao.module.system.dal.mysql.houselocation.WareHouseLocationMapper; import cn.iocoder.yudao.module.system.dal.mysql.information.DeviceInformationMapper; +import cn.iocoder.yudao.module.system.dal.mysql.log.RobotTaskDetailActionLogMapper; import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotChargeLogMapper; import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotInformationMapper; import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotTaskDetailMapper; @@ -49,6 +51,7 @@ import cn.iocoder.yudao.module.system.enums.robot.charge.ChargeTaskStatusEnum; import cn.iocoder.yudao.module.system.enums.robot.task.RobotCommandTypeEnum; //import cn.iocoder.yudao.module.system.service.robot.job.RobotCommonTaskService; import cn.iocoder.yudao.module.system.enums.wait.WaitStatusEnum; +import cn.iocoder.yudao.module.system.service.information.DeviceInformationService; import cn.iocoder.yudao.module.system.service.log.UserOperationLogService; import cn.iocoder.yudao.module.system.service.wait.MoveToWaitService; import cn.iocoder.yudao.module.system.util.redis.RedisUtil; @@ -154,6 +157,12 @@ public class RobotTaskServiceImpl extends ServiceImpl deviceNoMap = new HashMap<>(); - RobotChargeLogDO robotChargeLogs = null; - Integer robotStatus = RobotStatusEnum.DOING.getType(); - if (PathTaskTypeEnum.AUTO_CHARGE.getType().equals(taskAssignDTO.getType())) { - robotChargeLogs = chargeLogMapper.selectById(taskAssignDTO.getOrderId()); + if (PathTaskTypeEnum.AUTO_CHARGE.getType().equals(taskAssignDTO.getOrderType())) { + RobotChargeLogDO robotChargeLogs = chargeLogMapper.selectById(taskAssignDTO.getOrderId()); robotChargeLogs.setTaskStatus(ChargeTaskStatusEnum.DOING.getType()); - chargeLogMapper.updateBatch(robotChargeLogs); + chargeLogMapper.updateById(robotChargeLogs); robotStatus = RobotStatusEnum.CHARGE.getType(); if (ObjectUtil.isNotEmpty(robotChargeLogs.getTaskDetailId())) { @@ -482,10 +495,10 @@ public class RobotTaskServiceImpl extends ServiceImpl data = build.getData(); data.add(robotAssignTaskData); - } else if (PathTaskTypeEnum.CHARGE.getType().equals(taskAssignDTO.getType()) - || PathTaskTypeEnum.AUTO_CHARGE.getType().equals(taskAssignDTO.getType())) { + } else if (PathTaskTypeEnum.CHARGE.getType().equals(taskAssignDTO.getOrderType()) + || PathTaskTypeEnum.AUTO_CHARGE.getType().equals(taskAssignDTO.getOrderType())) { RobotAssignTaskDataDTO robotAssignTaskData = new RobotAssignTaskDataDTO(); robotAssignTaskData.setCommandType(RobotCommandTypeEnum.WORK_START_CHARGE.getType()); List data = build.getData(); @@ -549,8 +571,8 @@ public class RobotTaskServiceImpl extends ServiceImpl pageResult = null; PageResult dataPage = new PageResult<>(); List list = new ArrayList<>(); - if (ObjectUtil.isEmpty(pageReqVO.getRobotNo())) { + if (ObjectUtil.isEmpty(pageReqVO.getRobotNo()) && ObjectUtil.isEmpty(pageReqVO.getTaskStage())) { pageResult = taskMapper.selectPage(pageReqVO); dataPage.setTotal(pageResult.getTotal()); list = pageResult.getList(); @@ -1154,8 +1180,24 @@ public class RobotTaskServiceImpl extends ServiceImpl targetList = BeanUtil.copyToList(list, RobotTaskRespVO.class); - for (RobotTaskRespVO robotTaskRespVO : targetList) { - robotTaskRespVO.setDetails(taskDetailMapper.queryByTaskId(robotTaskRespVO.getId())); + if (ObjectUtil.isEmpty(targetList)) { + return dataPage; + } + + List takeIds = targetList.stream().map(RobotTaskRespVO::getId).collect(Collectors.toList()); + List taskDetailDOS = taskDetailMapper.selectList(new LambdaQueryWrapperX() + .in(RobotTaskDetailDO::getRobotTaskId, takeIds)); + + Map> detailMap = taskDetailDOS.stream().collect(Collectors.groupingBy(RobotTaskDetailDO::getRobotTaskId)); + + for (RobotTaskRespVO v : targetList) { + List details = detailMap.get(v.getId()); + if (ObjectUtil.isNotEmpty(pageReqVO.getTaskStage())) { + details = details.stream() + .filter(s -> s.getTaskStage().equals(pageReqVO.getTaskStage())) + .collect(Collectors.toList()); + } + v.setDetails(details); } dataPage.setList(targetList); return dataPage; @@ -1195,7 +1237,7 @@ public class RobotTaskServiceImpl extends ServiceImpl robotTaskIds = taskDetailDOS.stream() .map(RobotTaskDetailDO::getRobotTaskId) .collect(Collectors.toList()); @@ -1235,7 +1277,7 @@ public class RobotTaskServiceImpl extends ServiceImpl { task.setTaskStatus(RobotTaskStatusEnum.DOING.getType()); }); - taskMapper.updateBatch(tasks); + taskMapper.updateById(tasks); } if (TaskTypeEnum.TASK.getType().equals(distribution.getType())) { @@ -1264,8 +1306,9 @@ public class RobotTaskServiceImpl extends ServiceImpl() .eq(DeviceInformationDO::getDeviceNo, robotChargeLogDO.getDeviceNo())); deviceInformationDO.setDeviceUseStatus(DeviceUseStatusEnum.IDLE.getType()); - deviceInformationMapper.updateBatch(deviceInformationDO); + deviceInformationMapper.updateById(deviceInformationDO); log.info("充电桩设置为空闲 :{}", deviceInformationDO.getDeviceNo()); if (ObjectUtil.isEmpty(robotChargeLogDO.getTaskDetailId())) { @@ -1288,10 +1331,10 @@ public class RobotTaskServiceImpl extends ServiceImpl taskDetailDOS = getTaskDetailData(taskData,taskIdMap,v.getId()); taskDOList.add(taskData); taskDetailList.addAll(taskDetailDOS); + v.setRemainingCycleNumber(0l); } taskMapper.insertBatch(taskDOList); + taskMapper.updateById(taskList); taskDetailMapper.insertBatch(taskDetailList); List fromLocationIds = taskDetailList.stream().map(RobotTaskDetailDO::getFromLocationId).collect(Collectors.toList()); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/job/DistributeTasksServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/job/DistributeTasksServiceImpl.java index 18ea6487d..437dfd8f8 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/job/DistributeTasksServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/job/DistributeTasksServiceImpl.java @@ -98,6 +98,8 @@ public class DistributeTasksServiceImpl implements DistributeTasksService { lastTaskDetailMap = lastTaskDetails.stream().collect(Collectors.toMap(v -> v.getRobotNo(), Function.identity())); } + CommonConfigVO chargeConfig = JSONUtil.toBean(commonConfigDO.getConfigStr(), CommonConfigVO.class); + for (RobotInformationDO robot : robots) { String taskStatusKey = RobotTaskChcheConstant.ROBOT_TASK_STATUS + robot.getMacAddress(); String cargoDetectedKey = RobotTaskChcheConstant.ROBOT_CARGO_DETECTED + robot.getMacAddress(); @@ -114,6 +116,24 @@ public class DistributeTasksServiceImpl implements DistributeTasksService { continue; } + if (ObjectUtil.isNotEmpty(chargeConfig) && ObjectUtil.isNotEmpty(chargeConfig.getStartAutoCharge())) { + String pose2dKey = RobotTaskChcheConstant.ROBOT_INFORMATION_POSE_BAT_SOC + robot.getMacAddress(); + Object poseCache = redisUtil.get(pose2dKey); + RobotStatusDataPoseDTO dataPoseDTO = JSON.parseObject((String) poseCache, RobotStatusDataPoseDTO.class); + if (ObjectUtil.isEmpty(dataPoseDTO.getBatSoc())) { + robot.setRobotStatus(RobotStatusEnum.DOING.getType()); + log.info("车机没有电量信息 :{}",robot.getRobotNo()); + continue; + } + BigDecimal robotRemainingElectricity = new BigDecimal(dataPoseDTO.getBatSoc()); + BigDecimal robotEndElectricity = new BigDecimal(chargeConfig.getStartAutoCharge()+""); + if (robotRemainingElectricity.compareTo(robotEndElectricity) < 0) { + robot.setRobotStatus(RobotStatusEnum.DOING.getType()); + log.info("机器人的电量少于自动充电电量,不能接任务 :{}",robot.getRobotNo()); + continue; + } + } + if (ObjectUtil.isEmpty(cargoDetected) || RobotStatusCodeConstant.CARGO_DETECTED.equals(Boolean.parseBoolean(String.valueOf(cargoDetected)))) { robot.setRobotStatus(RobotStatusEnum.DOING.getType()); log.info("车机上报传感器被按下--不允许接任务 :{}",robot.getRobotNo()); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/job/RobotTaskAutoMoveServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/job/RobotTaskAutoMoveServiceImpl.java index cc0385845..75375bb46 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/job/RobotTaskAutoMoveServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/job/RobotTaskAutoMoveServiceImpl.java @@ -182,7 +182,7 @@ public class RobotTaskAutoMoveServiceImpl implements RobotTaskAutoMoveService { robotInformationDOS.stream().forEach(robotInformationDO -> { robotInformationDO.setRobotStatus(RobotStatusEnum.DOING.getType()); }); - robotInformationMapper.updateBatch(robotInformationDOS); + robotInformationMapper.updateById(robotInformationDOS); List locationIds = new ArrayList<>(); robotTaskAutoMoveDOS.forEach(robotTaskAutoMoveDO -> { diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/pathplanning/RobotPathPlanningServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/pathplanning/RobotPathPlanningServiceImpl.java index b24c08e17..892abc526 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/pathplanning/RobotPathPlanningServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/pathplanning/RobotPathPlanningServiceImpl.java @@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.mqtt.api.path.PathPlanningApi; import cn.iocoder.yudao.module.mqtt.api.path.task.TaskLimitationAreaDTO; import cn.iocoder.yudao.module.mqtt.api.path.task.TaskRobotNoLimittationAreaDTO; import cn.iocoder.yudao.module.mqtt.api.path.task.TaskToPathPlanningDTO; +import cn.iocoder.yudao.module.system.api.robot.dto.FloorZoneDTO; import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDataPoseDTO; import cn.iocoder.yudao.module.system.constant.path.PathPlanningTopicConstant; import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant; @@ -23,6 +24,7 @@ import cn.iocoder.yudao.module.system.dal.mysql.houselocation.WareHouseLocationM import cn.iocoder.yudao.module.system.dal.mysql.positionmap.PositionMapItemMapper; import cn.iocoder.yudao.module.system.dal.mysql.positionmap.PositionMapMapper; 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.dal.mysql.wait.MoveToWaitMapper; import cn.iocoder.yudao.module.system.enums.common.ZeroOneEnum; import cn.iocoder.yudao.module.system.enums.item.PositionMapItemEnum; @@ -93,6 +95,9 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService { @Resource private MoveToWaitMapper moveToWaitMapper; + @Autowired + private RobotTaskMapper robotTaskMapper; + /** * 下发任务给PP */ @@ -117,11 +122,46 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService { return; } + //停车不锁车 + taskDetailDOS = doPark(taskDetailDOS); + if (ObjectUtil.isEmpty(taskDetailDOS)) { + log.info("--不存在需要执行的任务---"); + return; + } + log.info("-------查找到车子和任务------"); distributeTasksToPP(robots, taskDetailDOS); } + /** + * 处理停车不锁车的任务 + * @param taskDetailDOS + * @return + */ + private List doPark(List taskDetailDOS) { + List parkList = new ArrayList<>(); + List detailList = new ArrayList<>(); + for (RobotTaskDetailDO v : taskDetailDOS) { + if (RobotTaskTypeEnum.PARK.getType().equals(v.getTaskType()) + && ZeroOneEnum.ZERO.getType().equals(v.getNeedLock())) { + parkList.add(v); + }else if (!RobotTaskTypeEnum.CHARGE.getType().equals(v.getTaskType())){ + detailList.add(v); + } + } + + if (ObjectUtil.isNotEmpty(parkList)) { + List detailIds = parkList.stream().map(RobotTaskDetailDO::getId).collect(Collectors.toList()); + List taskDetails = robotTaskDetailMapper.selectBatchIds(detailIds); + List taskIds = taskDetails.stream().map(RobotTaskDetailDO::getRobotTaskId).collect(Collectors.toList()); + robotTaskDetailMapper.updateDoneByIds(detailIds); + robotTaskMapper.updateDoneByIds(taskIds); + } + + return detailList; + } + /** * 派车辆去等待点 * @@ -159,7 +199,11 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService { continue; } - String mapKey = robotStatusDataPoseDTO.getFloor() + "_" + robotStatusDataPoseDTO.getArea(); + String floorAreaKey = RobotTaskChcheConstant.ROBOT_FLOOR_AREA + robot.getMacAddress(); + Object floorAreaObject = redisUtil.get(floorAreaKey); + FloorZoneDTO floorZoneDTO = JSONUtil.toBean((String) floorAreaObject, FloorZoneDTO.class); + + String mapKey = floorZoneDTO.getFloor() + "_" + floorZoneDTO.getArea(); PositionMapDO positionMapDO = positionMap.get(mapKey); if (ObjectUtil.isEmpty(positionMapDO)) { log.info("------此机器人没有匹配到楼层和区域------ :{}", robot.getRobotNo()); @@ -252,6 +296,7 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService { .priority(1l) .createTime(LocalDateTime.now()) .taskType(PathTaskTypeToRobotEnum.MOVE.getType()) + .waitIds(waitIds) .build(); pathPlanningList.add(pathPlanning); } @@ -348,6 +393,18 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService { //前一个任务是仅取货 List robotDoTake = getRobotDoTake(robots); + List positionMapItems = positionMapItemMapper.selectList(new LambdaQueryWrapperX() + .eq(PositionMapItemDO::getType, PositionMapItemEnum.STOP.getType()) + .eq(PositionMapItemDO::getUseStatus, ZeroOneEnum.ZERO.getType())); + List waitIds = null; + if (ObjectUtil.isNotEmpty(positionMapItems)) { + waitIds = positionMapItems + .stream() + .map(u -> u.getId() + "") + .collect(Collectors.toList()); + } + Integer i = 0; + log.info("开始组装需要下发给PP的任务"); for (RobotTaskDetailDO taskDetailDO : taskDetailDOS) { @@ -360,6 +417,15 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService { .createTime(taskDetailDO.getCreateTime()) .build(); + if (RobotTaskTypeEnum.PARK.getType().equals(taskDetailDO.getTaskType()) + && (ObjectUtil.isEmpty(waitIds) || waitIds.size() < i)) { + log.info("停车任务,没有多余的空闲点位 :{}",taskDetailDO.getId()); + return; + }else if (RobotTaskTypeEnum.PARK.getType().equals(taskDetailDO.getTaskType())) { + pathPlanning.setWaitIds(waitIds); + i++; + } + if (ObjectUtil.isNotEmpty(robotDoTake) && ObjectUtil.isNotEmpty(taskDetailDO.getRobotNo()) && robotDoTake.contains(taskDetailDO.getRobotNo()) && !RobotTaskTypeEnum.RELEASE.getType().equals(taskDetailDO.getTaskType())) { @@ -383,51 +449,36 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService { WareHouseLocationDO fromLocation = locationDOMap.get(taskDetailDO.getFromLocationId()); WareHouseLocationDO toLocation = locationDOMap.get(taskDetailDO.getToLocationId()); - //取是线库 - if (ObjectUtil.isNotEmpty(taskDetailDO.getFromLocationId()) - && ObjectUtil.isNotEmpty(taskDetailDO.getFromLaneId())) { - pathPlanning.setTakeGroupId("LINE_" + taskDetailDO.getFromLaneId()); + if (ObjectUtil.isNotEmpty(taskDetailDO.getFromLocationId())) { pathPlanning.setTakeLocationNumber(Math.abs(locationNumberReduce - taskDetailDO.getFromLocationNumber())); pathPlanning.setTakePointId(fromLocation.getMapItemId()); - pathPlanning.setTakeHeight(Double.valueOf(fromLocation.getLocationTrayHeight() + "")); - pathPlanning.setTakeLevel(fromLocation.getLocationStorey()); - pathPlanning.setTakeOffsetHeight(offsetHeight); - - } else if (ObjectUtil.isNotEmpty(taskDetailDO.getFromLocationId()) - && ObjectUtil.isEmpty(taskDetailDO.getFromLaneId())) { - //取的是普通点位 - pathPlanning.setTakeGroupId("POINT_" + taskDetailDO.getFromMapItemId()); - pathPlanning.setTakeLocationNumber(Math.abs(locationNumberReduce - taskDetailDO.getFromLocationNumber())); - pathPlanning.setTakePointId(fromLocation.getMapItemId()); - pathPlanning.setTakeHeight(Double.valueOf(fromLocation.getLocationTrayHeight() + "")); + if (ObjectUtil.isNotEmpty(fromLocation.getLocationTrayHeight())) { + pathPlanning.setTakeHeight(Double.valueOf(fromLocation.getLocationTrayHeight() + "")); + } pathPlanning.setTakeLevel(fromLocation.getLocationStorey()); pathPlanning.setTakeOffsetHeight(offsetHeight); + if (ObjectUtil.isNotEmpty(taskDetailDO.getFromLaneId())) { + pathPlanning.setTakeGroupId("LINE_" + taskDetailDO.getFromLaneId()); + }else { + pathPlanning.setTakeGroupId("POINT_" + taskDetailDO.getFromMapItemId()); + } } - //放是线库 - if (ObjectUtil.isNotEmpty(taskDetailDO.getToLocationId()) - && ObjectUtil.isNotEmpty(taskDetailDO.getToLaneId())) { - - pathPlanning.setReleaseGroupId("LINE_" + taskDetailDO.getToLaneId()); + if (ObjectUtil.isNotEmpty(taskDetailDO.getToLocationId())){ pathPlanning.setReleaseLocationNumber(taskDetailDO.getToLocationNumber()); pathPlanning.setReleasePointId(toLocation.getMapItemId()); - pathPlanning.setReleaseHeight(Double.valueOf(toLocation.getLocationTrayHeight() + "")); + if (ObjectUtil.isNotEmpty(toLocation.getLocationTrayHeight())) { + pathPlanning.setReleaseHeight(Double.valueOf(toLocation.getLocationTrayHeight() + "")); + } pathPlanning.setReleaseLevel(toLocation.getLocationStorey()); pathPlanning.setReleaseOffsetHeight(offsetHeight); - - } else if (ObjectUtil.isNotEmpty(taskDetailDO.getToLocationId()) - && ObjectUtil.isEmpty(taskDetailDO.getToLaneId())) { - //放的是普通点位 - pathPlanning.setReleaseGroupId("POINT_" + taskDetailDO.getToMapItemId()); - pathPlanning.setReleaseLocationNumber(taskDetailDO.getToLocationNumber()); - pathPlanning.setReleasePointId(toLocation.getMapItemId()); - pathPlanning.setReleaseHeight(Double.valueOf(toLocation.getLocationTrayHeight() + "")); - pathPlanning.setReleaseLevel(toLocation.getLocationStorey()); - pathPlanning.setReleaseOffsetHeight(offsetHeight); - + if (ObjectUtil.isNotEmpty(taskDetailDO.getToLaneId())){ + pathPlanning.setReleaseGroupId("LINE_" + taskDetailDO.getToLaneId()); + }else { + pathPlanning.setReleaseGroupId("POINT_" + taskDetailDO.getToMapItemId()); + } } - pathPlanningList.add(pathPlanning); } @@ -554,8 +605,6 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService { List detailDOS = taskDetailDOS.stream() .filter(v -> !laneIds.contains(v.getFromLaneId()) && !laneIds.contains(v.getToLaneId()) - && !RobotTaskTypeEnum.PARK.getType().equals(v.getTaskType()) //停车在充电的任务做 - && !RobotTaskTypeEnum.CHARGE.getType().equals(v.getTaskType()) //停车在充电的任务做 && !mapIds.contains(v.getFromMapItemId()) && !mapIds.contains(v.getToMapItemId())) .collect(Collectors.toList()); @@ -615,6 +664,8 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService { } else if (RobotTaskTypeEnum.TAKE.getType().equals(v.getTaskType())) { //仅取货 takeSetTask(list, v, fromLane, toLane, fromLocation, toLocation, toHaveFrom, fromHaveTo); + }else if (RobotTaskTypeEnum.PARK.getType().equals(v.getTaskType())) { + list.add(v); } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tool/ToolsServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tool/ToolsServiceImpl.java index 781f3ec78..9b84dec72 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tool/ToolsServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tool/ToolsServiceImpl.java @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.system.service.tool; import cn.hutool.core.util.ObjectUtil; import cn.hutool.json.JSONUtil; import cn.iocoder.yudao.module.mqtt.api.common.CommonApi; -import cn.iocoder.yudao.module.mqtt.api.path.PathPlanningApi; import cn.iocoder.yudao.module.mqtt.api.task.dto.RobotAcceptTaskDTO; import cn.iocoder.yudao.module.mqtt.enums.task.ExecutionTypeEnum; import cn.iocoder.yudao.module.system.api.path.vo.RobotClosePathPlantingDTO; @@ -21,7 +20,6 @@ import cn.iocoder.yudao.module.system.enums.config.CommandConfigTypeEnum; import cn.iocoder.yudao.module.system.enums.robot.RobotWarnType; import cn.iocoder.yudao.module.system.service.robot.RobotInformationService; import cn.iocoder.yudao.module.system.service.robot.RobotWarnMsgService; -import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -29,7 +27,6 @@ import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; -import javax.servlet.http.HttpServletResponse; import java.util.Arrays; import java.util.List; @@ -120,10 +117,10 @@ public class ToolsServiceImpl implements ToolsService { commonApi.commonMethod(closePathPlanting, PathPlanningTopicConstant.KILL_TASK); RobotAcceptTaskDTO robotTask = new RobotAcceptTaskDTO(); - robotTask.setOrder_id(taskDetailId); + robotTask.setOrderId(taskDetailId); String mac = robotInformationService.getMacByRobotNo(informationDO.getRobotNo()); robotTask.setTopic(RobotTopicConstant.ROBOT_TASK_TOPIC + mac); - robotTask.setExecution_type(ExecutionTypeEnum.CANCEL.getType()); + robotTask.setExecutionType(ExecutionTypeEnum.CANCEL.getType()); commonApi.commonMethod(robotTask, robotTask.getTopic()); return "关闭任务成功"; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/util/modbus3/ModbusUtils.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/util/modbus3/ModbusUtils.java new file mode 100644 index 000000000..d64897003 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/util/modbus3/ModbusUtils.java @@ -0,0 +1,195 @@ +package cn.iocoder.yudao.module.system.util.modbus3; + +import com.serotonin.modbus4j.ModbusFactory; +import com.serotonin.modbus4j.ModbusMaster; +import com.serotonin.modbus4j.code.DataType; +import com.serotonin.modbus4j.exception.ErrorResponseException; +import com.serotonin.modbus4j.exception.ModbusInitException; +import com.serotonin.modbus4j.exception.ModbusTransportException; +import com.serotonin.modbus4j.ip.IpParameters; +import com.serotonin.modbus4j.locator.BaseLocator; +import com.serotonin.modbus4j.msg.ModbusResponse; +import com.serotonin.modbus4j.msg.WriteRegistersRequest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ModbusUtils { + private static Logger log = LoggerFactory.getLogger(ModbusUtils.class); + /** + * 工厂。 + */ + static ModbusFactory modbusFactory; + + static { + if (modbusFactory == null) { + modbusFactory = new ModbusFactory(); + } + } + + /** + * 获取master + * + * @return + * @throws ModbusInitException + */ + public static ModbusMaster getMaster(String host, int port) throws ModbusInitException { + IpParameters params = new IpParameters(); + params.setHost(host); + params.setPort(port); + // +// modbusFactory.createRtuMaster(wapper); //RTU 协议 + // modbusFactory.createUdpMaster(params);//UDP 协议 + // modbusFactory.createAsciiMaster(wrapper);//ASCII 协议 + ModbusMaster master = modbusFactory.createTcpMaster(params, false);// TCP 协议 + master.init(); + + return master; + } + + public static ModbusMaster getRtuIpMaster(String host, int port) throws ModbusInitException { + IpParameters params = new IpParameters(); + params.setHost(host); + params.setPort(port); + params.setEncapsulated(true); + ModbusMaster master = modbusFactory.createTcpMaster(params, false); + try { + //设置超时时间 + master.setTimeout(1000); + //设置重连次数 + master.setRetries(3); + //初始化 + master.init(); + } catch (ModbusInitException e) { + e.printStackTrace(); + } + return master; + } + + /** + * + * @param portName 串口名 + * @param baudRate 波特率 + * @param dataBits 数据位 + * @param stopBits 中止位 + * @param parity 校验位 + * @return + * @throws ModbusInitException + */ + public static ModbusMaster getSerialPortRtuMaster(String portName, Integer baudRate, Integer dataBits, + Integer stopBits, Integer parity){ + // 设置串口参数,串口是COM1,波特率是9600 + // SerialPortWrapperImpl wrapper = new SerialPortWrapperImpl("COM2", 9600,SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE, 0, 0); + SerialPortWrapperImpl wrapper = new SerialPortWrapperImpl(portName, baudRate, + dataBits, stopBits, parity, 0, 0); + ModbusMaster master = modbusFactory.createRtuMaster(wrapper); + try { + //设置超时时间 + master.setTimeout(1000); + //设置重连次数 + master.setRetries(3); + //初始化 + master.init(); + } catch (ModbusInitException e) { + log.error("串口连接异常~"); + e.printStackTrace(); + } + return master; + } + /** + * + * @param portName 串口名 + * @param baudRate 波特率 + * @param dataBits 数据位 + * @param stopBits 中止位 + * @param parity 校验位 + * @return + * @throws ModbusInitException + */ + public static ModbusMaster getSerialPortAsciiMaster(String portName, Integer baudRate, Integer dataBits, + Integer stopBits, Integer parity){ + // 设置串口参数,串口是COM1,波特率是9600 + // SerialPortWrapperImpl wrapper = new SerialPortWrapperImpl("COM2", 9600,SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE, 0, 0); + SerialPortWrapperImpl wrapper = new SerialPortWrapperImpl(portName, baudRate, + dataBits, stopBits, parity, 0, 0); + ModbusMaster master = modbusFactory.createAsciiMaster(wrapper); + try { + //设置超时时间 + master.setTimeout(1000); + //设置重连次数 + master.setRetries(3); + //初始化 + master.init(); + } catch (ModbusInitException e) { + log.error("串口连接异常~"); + e.printStackTrace(); + } + return master; + } + + + /** + * 读取[01 Coil Status 0x]类型 开关数据 + * + * @param slaveId slaveId + * @param offset 位置 + * @return 读取值 + * @throws ModbusTransportException 异常 + * @throws ErrorResponseException 异常 + * @throws ModbusInitException 异常 + */ + public static Boolean readCoilStatus(ModbusMaster master, int slaveId, int offset) + throws ModbusTransportException, ErrorResponseException, ModbusInitException { + // 01 Coil Status + BaseLocator loc = BaseLocator.coilStatus(slaveId, offset); + Boolean value = master.getValue(loc); + return value; + } + /** + * 读取[03 Holding Register类型 2x]模拟量数据 + * + * @param slaveId slave Id + * @param offset 位置 + * @param dataType 数据类型,来自com.serotonin.modbus4j.code.DataType + * @return + * @throws ModbusTransportException 异常 + * @throws ErrorResponseException 异常 + * @throws ModbusInitException 异常 + */ + public static Number readHoldingRegister(ModbusMaster master, int slaveId, int offset, int dataType) + throws ModbusTransportException, ErrorResponseException, ModbusInitException { + // 03 Holding Register类型数据读取 + BaseLocator loc = BaseLocator.holdingRegister(slaveId, offset, dataType); + Number value = master.getValue(loc); + return value; + } + + /** + * 读取[04 Input Registers 3x]类型 模拟量数据 + * + * @param slaveId slaveId + * @param offset 位置 + * @param dataType 数据类型,来自com.serotonin.modbus4j.code.DataType + * @return 返回结果 + * @throws ModbusTransportException 异常 + * @throws ErrorResponseException 异常 + * @throws ModbusInitException 异常 + */ + public static Number readInputRegisters(ModbusMaster master, int slaveId, int offset, int dataType) + throws ModbusTransportException, ErrorResponseException, ModbusInitException { + // 04 Input Registers类型数据读取 + BaseLocator loc = BaseLocator.inputRegister(slaveId, offset, dataType); + Number value = master.getValue(loc); + return value; + } + + /** + * 向Modbus设备的保持寄存器写入值 + * slaveId 设备序列号 + * startOffset 写入寄存器开始的地址 + * values 写入寄存器里的值 + */ + public static void writeHoldingRegisters(ModbusMaster master, int slaveId, int startOffset, short[] values) throws ModbusTransportException { + WriteRegistersRequest request = new WriteRegistersRequest(slaveId, startOffset, values); + master.send(request); + } +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/util/modbus3/SerialInputStream.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/util/modbus3/SerialInputStream.java new file mode 100644 index 000000000..e4eaeb319 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/util/modbus3/SerialInputStream.java @@ -0,0 +1,221 @@ +package cn.iocoder.yudao.module.system.util.modbus3; + + +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +import jssc.SerialPort; + +import java.io.IOException; +import java.io.InputStream; + +/** + * Class that wraps a {@link SerialPort} to provide {@link InputStream} + * functionality. This stream also provides support for performing blocking + * reads with timeouts. + *
+ * It is instantiated by passing the constructor a {@link SerialPort} instance. + * Do not create multiple streams for the same serial port unless you implement + * your own synchronization. + * + * @author Charles Hache + * + * Attribution: https://github.com/therealchalz/java-simple-serial-connector + * + */ +public class SerialInputStream extends InputStream { + + private SerialPort serialPort; + private int defaultTimeout = 0; + + /** + * Instantiates a SerialInputStream for the given {@link SerialPort} Do not + * create multiple streams for the same serial port unless you implement + * your own synchronization. + * + * @param sp The serial port to stream. + */ + public SerialInputStream(SerialPort sp) { + serialPort = sp; + } + + /** + * Set the default timeout (ms) of this SerialInputStream. This affects + * subsequent calls to {@link #read()}, {@link #(int[])}, and + * {@link #(int[], int, int)} The default timeout can be 'unset' + * by setting it to 0. + * + * @param time The timeout in milliseconds. + */ + public void setTimeout(int time) { + defaultTimeout = time; + } + + /** + * Reads the next byte from the port. If the timeout of this stream has been + * set, then this method blocks until data is available or until the timeout + * has been hit. If the timeout is not set or has been set to 0, then this + * method blocks indefinitely. + */ + @Override + public int read() throws IOException { + return read(defaultTimeout); + } + + /** + * The same contract as {@link #read()}, except overrides this stream's + * default timeout with the given timeout in milliseconds. + * + * @param timeout The timeout in milliseconds. + * @return The read byte. + * @throws IOException On serial port error or timeout + */ + public int read(int timeout) throws IOException { + byte[] buf = new byte[1]; + try { + if (timeout > 0) { + buf = serialPort.readBytes(1, timeout); + } else { + buf = serialPort.readBytes(1); + } + return buf[0]; + } catch (Exception e) { + throw new IOException(e); + } + } + + /** + * Non-blocking read of up to buf.length bytes from the stream. This call + * behaves as read(buf, 0, buf.length) would. + * + * @param buf The buffer to fill. + * @return The number of bytes read, which can be 0. + * @throws IOException on error. + */ + @Override + public int read(byte[] buf) throws IOException { + return read(buf, 0, buf.length); + } + + /** + * Non-blocking read of up to length bytes from the stream. This method + * returns what is immediately available in the input buffer. + * + * @param buf The buffer to fill. + * @param offset The offset into the buffer to start copying data. + * @param length The maximum number of bytes to read. + * @return The actual number of bytes read, which can be 0. + * @throws IOException on error. + */ + @Override + public int read(byte[] buf, int offset, int length) throws IOException { + + if (buf.length < offset + length) { + length = buf.length - offset; + } + + int available = this.available(); + + if (available > length) { + available = length; + } + + try { + byte[] readBuf = serialPort.readBytes(available); +// System.arraycopy(readBuf, 0, buf, offset, length); + System.arraycopy(readBuf, 0, buf, offset, readBuf.length); + return readBuf.length; + } catch (Exception e) { + throw new IOException(e); + } + } + + /** + * Blocks until buf.length bytes are read, an error occurs, or the default + * timeout is hit (if specified). This behaves as blockingRead(buf, 0, + * buf.length) would. + * + * @param buf The buffer to fill with data. + * @return The number of bytes read. + * @throws IOException On error or timeout. + */ + public int blockingRead(byte[] buf) throws IOException { + return blockingRead(buf, 0, buf.length, defaultTimeout); + } + + /** + * The same contract as {@link #blockingRead(byte[])} except overrides this + * stream's default timeout with the given one. + * + * @param buf The buffer to fill. + * @param timeout The timeout in milliseconds. + * @return The number of bytes read. + * @throws IOException On error or timeout. + */ + public int blockingRead(byte[] buf, int timeout) throws IOException { + return blockingRead(buf, 0, buf.length, timeout); + } + + /** + * Blocks until length bytes are read, an error occurs, or the default + * timeout is hit (if specified). Saves the data into the given buffer at + * the specified offset. If the stream's timeout is not set, behaves as + * {@link #read(byte[], int, int)} would. + * + * @param buf The buffer to fill. + * @param offset The offset in buffer to save the data. + * @param length The number of bytes to read. + * @return the number of bytes read. + * @throws IOException on error or timeout. + */ + public int blockingRead(byte[] buf, int offset, int length) throws IOException { + return blockingRead(buf, offset, length, defaultTimeout); + } + + /** + * The same contract as {@link #blockingRead(byte[], int, int)} except + * overrides this stream's default timeout with the given one. + * + * @param buf The buffer to fill. + * @param offset Offset in the buffer to start saving data. + * @param length The number of bytes to read. + * @param timeout The timeout in milliseconds. + * @return The number of bytes read. + * @throws IOException On error or timeout. + */ + public int blockingRead(byte[] buf, int offset, int length, int timeout) throws IOException { + if (buf.length < offset + length) { + throw new IOException("Not enough buffer space for serial data"); + } + + if (timeout < 1) { + return read(buf, offset, length); + } + + try { + byte[] readBuf = serialPort.readBytes(length, timeout); + System.arraycopy(readBuf, 0, buf, offset, length); + return readBuf.length; + } catch (Exception e) { + throw new IOException(e); + } + } + + @Override + public int available() throws IOException { + int ret; + try { + ret = serialPort.getInputBufferBytesCount(); + if (ret >= 0) { + return ret; + } + throw new IOException("Error checking available bytes from the serial port."); + } catch (Exception e) { + throw new IOException("Error checking available bytes from the serial port."); + } + } + +} + diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/util/modbus3/SerialOutputStream.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/util/modbus3/SerialOutputStream.java new file mode 100644 index 000000000..d3c3af0c7 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/util/modbus3/SerialOutputStream.java @@ -0,0 +1,84 @@ +package cn.iocoder.yudao.module.system.util.modbus3; + + +/** + * + * Copyright (c) 2009-2020 Freedomotic Team http://www.freedomotic-iot.com + * + * This file is part of Freedomotic + * + * This Program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2, or (at your option) any later version. + * + * This Program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * Freedomotic; see the file COPYING. If not, see + * . + */ + +import jssc.SerialPort; +import jssc.SerialPortException; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * Class that wraps a {@link SerialPort} to provide {@link OutputStream} + * functionality. + *
+ * It is instantiated by passing the constructor a {@link SerialPort} instance. + * Do not create multiple streams for the same serial port unless you implement + * your own synchronization. + * + * @author Charles Hache + * + * Attribution: https://github.com/therealchalz/java-simple-serial-connector + * + */ +public class SerialOutputStream extends OutputStream { + + SerialPort serialPort; + + /** + * Instantiates a SerialOutputStream for the given {@link SerialPort} Do not + * create multiple streams for the same serial port unless you implement + * your own synchronization. + * + * @param sp The serial port to stream. + */ + public SerialOutputStream(SerialPort sp) { + serialPort = sp; + } + + @Override + public void write(int b) throws IOException { + try { + serialPort.writeInt(b); + } catch (SerialPortException e) { + throw new IOException(e); + } + } + + @Override + public void write(byte[] b) throws IOException { + write(b, 0, b.length); + + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + byte[] buffer = new byte[len]; + System.arraycopy(b, off, buffer, 0, len); + try { + serialPort.writeBytes(buffer); + } catch (SerialPortException e) { + throw new IOException(e); + } + } +} + diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/util/modbus3/SerialPortMasterTest.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/util/modbus3/SerialPortMasterTest.java new file mode 100644 index 000000000..b019bea27 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/util/modbus3/SerialPortMasterTest.java @@ -0,0 +1,43 @@ +package cn.iocoder.yudao.module.system.util.modbus3; + + +import com.serotonin.modbus4j.ModbusMaster; +import com.serotonin.modbus4j.code.DataType; +import com.serotonin.modbus4j.exception.ErrorResponseException; +import com.serotonin.modbus4j.exception.ModbusInitException; +import com.serotonin.modbus4j.exception.ModbusTransportException; +import com.serotonin.modbus4j.locator.BaseLocator; + +public class SerialPortMasterTest { + public static void main(String[] args) throws ModbusTransportException, ErrorResponseException, ModbusInitException { + //ModbusMaster master = ModbusUtils.getSerialPortRtuMaster("COM2", 9600, 8, 1, 0); + //float v = ModbusUtils.readHoldingRegister(master, 1, 2, DataType.FOUR_BYTE_FLOAT).floatValue(); + //System.out.println(v); + +// ModbusMaster asciiMaster = ModbusUtils.getSerialPortAsciiMaster("COM2", 38400, 8, 1, 0); + ModbusMaster asciiMaster = ModbusUtils.getMaster("192.168.10.234", 8899); + /*float f = ModbusUtils.readHoldingRegister(asciiMaster, 1, 0, DataType.FOUR_BYTE_FLOAT).floatValue(); + System.out.println(f);*/ + + //缩回去 + short[] arr = {1}; + + //伸出来 +// short[] arr = {1}; + ModbusUtils.writeHoldingRegisters(asciiMaster,1,0,arr); + asciiMaster.destroy(); + } + + public void query() { + try { + ModbusMaster master = ModbusUtils.getMaster("192.168.10.234", 8899); + BaseLocator loc = BaseLocator.holdingRegister(1, 9, DataType.TWO_BYTE_INT_UNSIGNED); + Number value = master.getValue(loc); + byte b = value.byteValue(); + System.out.println("----------"+b); + System.out.println("结果 "+ value.longValue()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/util/modbus3/SerialPortWrapperImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/util/modbus3/SerialPortWrapperImpl.java new file mode 100644 index 000000000..ecac7eccd --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/util/modbus3/SerialPortWrapperImpl.java @@ -0,0 +1,129 @@ +package cn.iocoder.yudao.module.system.util.modbus3; + +/** + * + * Copyright (c) 2009-2020 Freedomotic Team http://www.freedomotic-iot.com + * + * This file is part of Freedomotic + * + * This Program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2, or (at your option) any later version. + * + * This Program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * Freedomotic; see the file COPYING. If not, see + * . + */ + +import com.serotonin.modbus4j.serial.SerialPortWrapper; +import jssc.SerialPort; +import jssc.SerialPortException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.InputStream; +import java.io.OutputStream; + +/** + * + */ +public class SerialPortWrapperImpl implements SerialPortWrapper { + + private static final Logger LOG = LoggerFactory.getLogger(SerialPortWrapperImpl.class); + private SerialPort port; + private String commPortId; + private int baudRate; + private int dataBits; + private int stopBits; + private int parity; + private int flowControlIn; + private int flowControlOut; + + public SerialPortWrapperImpl(String commPortId, int baudRate, int dataBits, int stopBits, int parity, int flowControlIn, + int flowControlOut) { + + this.commPortId = commPortId; + this.baudRate = baudRate; + this.dataBits = dataBits; + this.stopBits = stopBits; + this.parity = parity; + this.flowControlIn = flowControlIn; + this.flowControlOut = flowControlOut; + + port = new SerialPort(this.commPortId); + + } + + @Override + public void close() throws Exception { + port.closePort(); + //listeners.forEach(PortConnectionListener::closed); + LOG.debug("Serial port {} closed", port.getPortName()); + } + + @Override + public void open() { + try { + port.openPort(); + port.setParams(this.getBaudRate(), this.getDataBits(), this.getStopBits(), this.getParity()); + port.setFlowControlMode(this.getFlowControlIn() | this.getFlowControlOut()); + + //listeners.forEach(PortConnectionListener::opened); + LOG.debug("Serial port {} opened", port.getPortName()); + } catch (SerialPortException ex) { + LOG.error("Error opening port : {} for {} ", port.getPortName(), ex); + } + } + + @Override + public InputStream getInputStream() { + return new SerialInputStream(port); + } + + @Override + public OutputStream getOutputStream() { + return new SerialOutputStream(port); + } + + @Override + public int getBaudRate() { + return baudRate; + //return SerialPort.BAUDRATE_9600; + } + + @Override + public int getFlowControlIn() { + return flowControlIn; + //return SerialPort.FLOWCONTROL_NONE; + } + + @Override + public int getFlowControlOut() { + return flowControlOut; + //return SerialPort.FLOWCONTROL_NONE; + } + + @Override + public int getDataBits() { + return dataBits; + //return SerialPort.DATABITS_8; + } + + @Override + public int getStopBits() { + return stopBits; + //return SerialPort.STOPBITS_1; + } + + @Override + public int getParity() { + return parity; + //return SerialPort.PARITY_NONE; + } +} + diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/application-local.yaml b/yudao-module-system/yudao-module-system-biz/src/main/resources/application-local.yaml index 78e87470e..2ea7cdc98 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/resources/application-local.yaml +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/application-local.yaml @@ -226,7 +226,6 @@ zn: robot_position_cache_time: 10 #机器人上报点位存储时间(秒) cycle_do_auto_move: true #存在循环的任务,是否开启自动移库. true:存在循环任务,开启自动移库; false:有循环任务不自动移库 full_electricity: 100 #机器人充满电的电量 - robot_error_level_time: 30 #机器人异常存储时间(秒) task_need_single: true #机器人对同一线库/点位是不是只能有一台机器人做任务 (true:一个点位/线库,只有一台机器人) location_number_reduce: 100000000 #库位排序的差值(下发取货任务,将库位排序减去此值,然后取绝对值) robot_doing_action: # 机器人正在做的动作 @@ -240,4 +239,5 @@ zn: robot_config: #机器人取放货默认配置 offset_height: 0.1 #叉起货需要在原来高度基础上偏移的高度 default_tray_height: 1.1 #默认每层高度 + open_rate_limiter: true #是否开启限流 diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/robot/RobotTaskDetailActionLogMapper.xml b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/robot/RobotTaskDetailActionLogMapper.xml index 5b603e5a9..5232fdc0d 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/robot/RobotTaskDetailActionLogMapper.xml +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/robot/RobotTaskDetailActionLogMapper.xml @@ -9,4 +9,13 @@ 文档可见:https://www.iocoder.cn/MyBatis/x-plugins/ --> + + update + robot_task_detail_action_log + set + action_status = #{actionStatus} + where + task_detail_id = #{taskDetailId} + and command_id = '-1' + \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/robot/RobotTaskDetailMapper.xml b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/robot/RobotTaskDetailMapper.xml index dbe3b29fc..79f2fc7ee 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/robot/RobotTaskDetailMapper.xml +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/robot/RobotTaskDetailMapper.xml @@ -28,6 +28,7 @@ + @@ -70,6 +71,7 @@ from_location_number, to_location_number, from_map_item_id, + need_lock, to_map_item_id @@ -317,6 +319,19 @@ where id = #{id} + + update + robot_task_detail + set + task_status = '2', + task_stage = '5' + where + id in + + #{id} + + diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/robot/RobotTaskMapper.xml b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/robot/RobotTaskMapper.xml index 69c3c054b..71cfcd27c 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/robot/RobotTaskMapper.xml +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/robot/RobotTaskMapper.xml @@ -278,7 +278,7 @@ and t1.task_status = #{pageReqVO.taskStatus} - and t1.task_stage = #{pageReqVO.taskStage} + and t2.task_stage = #{pageReqVO.taskStage} and t2.robot_no like concat('%', #{pageReqVO.robotNo}, '%') @@ -461,6 +461,19 @@ where id = #{id} + + update + robot_task + set + task_status = '2', + task_stage = '5' + where + id in + + #{id} + + diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/robot/RobotWarnMsgMapper.xml b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/robot/RobotWarnMsgMapper.xml index c1708cdb0..8021c8e8e 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/robot/RobotWarnMsgMapper.xml +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/robot/RobotWarnMsgMapper.xml @@ -13,8 +13,10 @@ update robot_warn_msg set - read_status = '1' + read_status = '1', + read_time = now() where read_status = '0' + LIMIT 1000 \ No newline at end of file