下发任务校验电量

This commit is contained in:
cbs 2025-02-10 17:28:55 +08:00
parent 5bb04952be
commit 3b3d6a5e7f
46 changed files with 789 additions and 23 deletions

View File

@ -12,6 +12,7 @@ public class RobotAcceptTaskDTO {
private String order_id;
private String order_type = "";
private String topic;
private String execution_type;
private List<RobotAcceptTaskData> data;
}

View File

@ -226,4 +226,7 @@ public interface ErrorCodeConstants {
// ========== 通用配置 1_002_042_001 ==========
ErrorCode CONFIG_NOT_EXISTS = new ErrorCode(1_002_042_001 , "通用配置不存在");
// ========== 车辆充电记录 1_002_043_001 ==========
ErrorCode CHARGE_LOG_NOT_EXISTS = new ErrorCode(1_002_043_001, "车辆充电记录不存在");
}

View File

@ -4,6 +4,7 @@ import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
/**
* 项目的启动类
@ -16,6 +17,7 @@ import org.springframework.context.annotation.Configuration;
*/
@SpringBootApplication
@EnableCaching
@EnableAsync
public class SystemServerApplication {
public static void main(String[] args) {

View File

@ -13,6 +13,7 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.math.BigDecimal;
@Slf4j
@RestController // 提供 RESTful API 接口 Feign 调用
@ -40,7 +41,14 @@ public class RobotGenericsStatusApiImpl implements RobotGenericsStatusApi {
RobotStatusDataPoseDTO robotStatusDataPoseDTO= JSONUtil.toBean((String)object, RobotStatusDataPoseDTO.class);
robotStatusDataPoseDTO.setArea(robotStatusData.getData().getZone());
robotStatusDataPoseDTO.setFloor(robotStatusData.getData().getFloor());
robotStatusDataPoseDTO.setBat_soc(robotStatusData.getData().getHw_states().getBat_soc());
String batSoc = robotStatusData.getData().getHw_states().getBat_soc();
if (ObjectUtil.isNotEmpty(batSoc)) {
BigDecimal a = new BigDecimal(batSoc);
BigDecimal b = new BigDecimal("100");
BigDecimal multiply = a.multiply(b);
robotStatusDataPoseDTO.setBat_soc(multiply.toString());
}
redisUtil.set(pose2dKey,JSON.toJSONString(robotStatusDataPoseDTO),robotPositionCacheTime);
}

View File

@ -13,8 +13,11 @@ import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDetailDO;
import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotInformationMapper;
import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotTaskDetailMapper;
import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotTaskMapper;
import cn.iocoder.yudao.module.system.enums.robot.CommandTypeEnum;
import cn.iocoder.yudao.module.system.enums.robot.RobotStatusEnum;
import cn.iocoder.yudao.module.system.enums.robot.RobotTaskDetailStatusEnum;
import cn.iocoder.yudao.module.system.enums.robot.task.RobotTaksOrderTypeEnum;
import cn.iocoder.yudao.module.system.service.robot.job.RobotCommonTaskService;
import cn.iocoder.yudao.module.system.util.redis.RedisUtil;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
@ -90,14 +93,23 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
robotTaskMapper.updateRobot(robotTaskDO);
}
//更新机器人任务状态
if (RobotExecutionStateConstant.DONE.equals(robotCompleteTaskDTO.getExecution_state()) ||
RobotExecutionStateConstant.CLOSE.equals(robotCompleteTaskDTO.getExecution_state())) {
if ((RobotExecutionStateConstant.DONE.equals(robotCompleteTaskDTO.getExecution_state()) ||
RobotExecutionStateConstant.CLOSE.equals(robotCompleteTaskDTO.getExecution_state()))
&& !RobotTaksOrderTypeEnum.AUTO_CHARGE.getType().equals(robotCompleteTaskDTO.getOrder_type())) {
RobotInformationDO query = new RobotInformationDO();
query.setMacAddress(robotCompleteTaskDTO.getMac());
List<RobotInformationDO> existRobotMac = robotInformationMapper.queryAllByLimit(query);
String robotNo = existRobotMac.get(0).getRobotNo();
robotInformationMapper.updateRobotStatus(robotNo, RobotStatusEnum.STAND_BY.getType());
redisUtil.del(robotDoingActionKey);
} else if (RobotExecutionStateConstant.DONE.equals(robotCompleteTaskDTO.getExecution_state())
&& RobotTaksOrderTypeEnum.AUTO_CHARGE.getType().equals(robotCompleteTaskDTO.getOrder_type())) {
RobotInformationDO query = new RobotInformationDO();
query.setMacAddress(robotCompleteTaskDTO.getMac());
List<RobotInformationDO> existRobotMac = robotInformationMapper.queryAllByLimit(query);
String robotNo = existRobotMac.get(0).getRobotNo();
robotInformationMapper.updateRobotStatus(robotNo, RobotStatusEnum.CHARGE.getType());
redisUtil.set(robotDoingActionKey, CommandTypeEnum.CHARGE.getType());
}
return CommonResult.success(true);

View File

@ -0,0 +1,26 @@
package cn.iocoder.yudao.module.system.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ThreadPoolExecutor;
@Configuration(proxyBeanMethods = false)
public class SystemJobConfiguration {
public static final String NOTIFY_THREAD_POOL_TASK_EXECUTOR = "NOTIFY_THREAD_POOL_TASK_EXECUTOR";
@Bean(NOTIFY_THREAD_POOL_TASK_EXECUTOR)
public ThreadPoolTaskExecutor notifyThreadPoolTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(8); // 设置核心线程数
executor.setMaxPoolSize(16); // 设置最大线程数
executor.setKeepAliveSeconds(60); // 设置空闲时间
executor.setQueueCapacity(100); // 设置队列大小
executor.setThreadNamePrefix("notify-task-"); // 配置线程池的前缀
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 进行加载
executor.initialize();
return executor;
}
}

View File

@ -16,4 +16,7 @@ public class RobotTaskChcheConstant {
//机器人正在做的动作
public static String ROBOT_DOING_ACTION = "robot:information:doing:action";
//机器人充电模式 1:自动充电2:机会充电3:充满电
public static String ROBOT_CHARGE_MODEL = "robot:information:charge:model";
}

View File

@ -15,7 +15,7 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
@ToString(callSuper = true)
public class CommonConfigPageReqVO extends PageParam {
@Schema(description = "类型1:参数配置、2备用", example = "1")
@Schema(description = "类型1:参数配置", example = "1")
private Integer configType;
@Schema(description = "配置信息")

View File

@ -16,8 +16,8 @@ public class CommonConfigRespVO {
@ExcelProperty("主键ID")
private Long id;
@Schema(description = "类型1:参数配置、2备用", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@ExcelProperty("类型1:参数配置、2:备用")
@Schema(description = "类型1:参数配置", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@ExcelProperty("类型1:参数配置、2:充满电周期对应的冲电量、3:能做任务的最低电量")
private Integer configType;
@Schema(description = "配置信息")

View File

@ -17,7 +17,7 @@ public class CommonConfigSaveReqVO implements Serializable {
private Long id;
//查看 CommandConfigTypeEnum
@Schema(description = "类型1:参数配置、2备用", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@Schema(description = "类型1:参数配置)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer configType;
@Schema(description = "配置信息")

View File

@ -24,14 +24,15 @@ public class CommonConfigVO {
private Integer chanceChargeEnd;
@Schema(description = "定时充电时段-开始时间")
private LocalDateTime chargeStartTime;
private LocalDateTime scheduleChargeStartTime;
@Schema(description = "定时充电时段-结束时间")
private LocalDateTime chargeEndTime;
private LocalDateTime scheduleChargeEndTime;
@Schema(description = "冲满电周期")
@Schema(description = "冲满电周期(天)")
private Integer chanceCycle;
@Schema(description = "遇障告警设置-等待时间")
private Integer warnWaitTime;
}

View File

@ -0,0 +1,95 @@
package cn.iocoder.yudao.module.system.controller.admin.robot;
import cn.iocoder.yudao.module.system.controller.admin.robot.chargelog.*;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotChargeLogDO;
import cn.iocoder.yudao.module.system.service.robot.chargelog.RobotChargeLogService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import javax.validation.constraints.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
@Tag(name = "管理后台 - 车辆充电记录")
@RestController
@RequestMapping("/robot/charge-log")
@Validated
public class RobotChargeLogController {
@Resource
private RobotChargeLogService chargeLogService;
@PostMapping("/create")
@Operation(summary = "创建车辆充电记录")
@PreAuthorize("@ss.hasPermission('robot:charge-log:create')")
public CommonResult<Long> createChargeLog(@Valid @RequestBody RobotChargeLogSaveReqVO createReqVO) {
return success(chargeLogService.createChargeLog(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新车辆充电记录")
@PreAuthorize("@ss.hasPermission('robot:charge-log:update')")
public CommonResult<Boolean> updateChargeLog(@Valid @RequestBody RobotChargeLogSaveReqVO updateReqVO) {
chargeLogService.updateChargeLog(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除车辆充电记录")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('robot:charge-log:delete')")
public CommonResult<Boolean> deleteChargeLog(@RequestParam("id") Long id) {
chargeLogService.deleteChargeLog(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得车辆充电记录")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('robot:charge-log:query')")
public CommonResult<RobotChargeLogRespVO> getChargeLog(@RequestParam("id") Long id) {
RobotChargeLogDO chargeLog = chargeLogService.getChargeLog(id);
return success(BeanUtils.toBean(chargeLog, RobotChargeLogRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得车辆充电记录分页")
@PreAuthorize("@ss.hasPermission('robot:charge-log:query')")
public CommonResult<PageResult<RobotChargeLogRespVO>> getChargeLogPage(@Valid RobotChargeLogPageReqVO pageReqVO) {
PageResult<RobotChargeLogDO> pageResult = chargeLogService.getChargeLogPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, RobotChargeLogRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出车辆充电记录 Excel")
@PreAuthorize("@ss.hasPermission('robot:charge-log:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportChargeLogExcel(@Valid RobotChargeLogPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<RobotChargeLogDO> list = chargeLogService.getChargeLogPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "车辆充电记录.xls", "数据", RobotChargeLogRespVO.class,
BeanUtils.toBean(list, RobotChargeLogRespVO.class));
}
}

View File

@ -0,0 +1,41 @@
package cn.iocoder.yudao.module.system.controller.admin.robot.chargelog;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 车辆充电记录分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class RobotChargeLogPageReqVO extends PageParam {
@Schema(description = "AGV编号")
private String robotNo;
@Schema(description = "开始充电电量")
private Integer startElectricity;
@Schema(description = "结束充电电量")
private Integer endElectricity;
@Schema(description = "充电模式(1:自动充电、2:机会充电、3:充满电)")
private Integer chargeModel;
@Schema(description = "结束充电时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] endTime;
@Schema(description = "device_information表的设备编号")
private String deviceNo;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

View File

@ -0,0 +1,47 @@
package cn.iocoder.yudao.module.system.controller.admin.robot.chargelog;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;
@Schema(description = "管理后台 - 车辆充电记录 Response VO")
@Data
@ExcelIgnoreUnannotated
public class RobotChargeLogRespVO {
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "6554")
@ExcelProperty("主键ID")
private Long id;
@Schema(description = "AGV编号")
@ExcelProperty("AGV编号")
private String robotNo;
@Schema(description = "开始充电电量")
@ExcelProperty("开始充电电量")
private Integer startElectricity;
@Schema(description = "结束充电电量")
@ExcelProperty("结束充电电量")
private Integer endElectricity;
@Schema(description = "充电模式(1:自动充电、2:机会充电、3:充满电)")
@ExcelProperty("充电模式(1:自动充电、2:机会充电、3:充满电)")
private Integer chargeModel;
@Schema(description = "结束充电时间")
@ExcelProperty("结束充电时间")
private LocalDateTime endTime;
@Schema(description = "device_information表的设备编号")
@ExcelProperty("device_information表的设备编号")
private String deviceNo;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}

View File

@ -0,0 +1,35 @@
package cn.iocoder.yudao.module.system.controller.admin.robot.chargelog;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 车辆充电记录新增/修改 Request VO")
@Data
public class RobotChargeLogSaveReqVO {
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "6554")
private Long id;
@Schema(description = "AGV编号")
private String robotNo;
@Schema(description = "开始充电电量")
private Integer startElectricity;
@Schema(description = "结束充电电量")
private Integer endElectricity;
@Schema(description = "充电模式(1:自动充电、2:机会充电、3:充满电)")
private Integer chargeModel;
@Schema(description = "结束充电时间")
private LocalDateTime endTime;
@Schema(description = "device_information表的设备编号")
private String deviceNo;
}

View File

@ -46,4 +46,7 @@ public class RobotInformationPageReqVO extends PageParam {
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
@Schema(description = "是否自动充电0:手动充电,1:自动充电)")
private Integer chargeType;
}

View File

@ -64,4 +64,7 @@ public class RobotInformationPageRespVO {
@Schema(description = "楼层/区域(json)")
private Set<Long> floorAreaJson;
@Schema(description = "是否自动充电0:手动充电,1:自动充电)")
private Integer chargeType;
}

View File

@ -66,5 +66,9 @@ public class RobotInformationRespVO {
@ExcelProperty("自动充电电量")
private Integer autoCharge;
@Schema(description = "是否自动充电0:手动充电,1:自动充电)")
@ExcelProperty("是否自动充电0:手动充电,1:自动充电)")
private Integer chargeType;
}

View File

@ -46,4 +46,6 @@ public class RobotInformationSaveReqVO {
@Schema(description = "自动充电电量")
private Integer autoCharge;
@Schema(description = "是否自动充电0:手动充电,1:自动充电)")
private Integer chargeType;
}

View File

@ -32,5 +32,5 @@ public class RobotModelPageReqVO extends PageParam {
private String url;
@Schema(description = "是否自动充电0:手动充电,1:自动充电)")
private Integer autoCharge;
private Integer chargeType;
}

View File

@ -25,7 +25,7 @@ public class RobotModelRespVO {
private String url;
@Schema(description = "是否自动充电0:手动充电,1:自动充电)")
private Integer autoCharge;
private Integer chargeType;
@Schema(description = "偏移量")
@ExcelProperty("偏移量")

View File

@ -23,6 +23,6 @@ public class RobotModelSaveReqVO {
private String url;
@Schema(description = "是否自动充电0:手动充电,1:自动充电)")
private Integer autoCharge;
private Integer chargeType;
}

View File

@ -28,7 +28,7 @@ public class CommonConfigDO extends BaseDO {
@TableId(type = IdType.ASSIGN_ID)
private Long id;
/**
* 类型1:参数配置2备用
* 类型1:参数配置
*/
private Integer configType;
/**

View File

@ -0,0 +1,58 @@
package cn.iocoder.yudao.module.system.dal.dataobject.robot;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* 车辆充电记录 DO
*
* @author 陈宾顺
*/
@TableName("robot_charge_log")
@KeySequence("robot_charge_log_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class RobotChargeLogDO extends BaseDO {
/**
* 主键ID
*/
@TableId
private Long id;
/**
* AGV编号
*/
private String robotNo;
/**
* 开始充电电量
*/
private Integer startElectricity;
/**
* 结束充电电量
*/
private Integer endElectricity;
/**
* 结束充电时间
*/
private LocalDateTime endTime;
/**
* device_information表的设备编号
*/
private String deviceNo;
/**
* 充电模式(1:自动充电2:机会充电3:充满电)
*/
private Integer chargeModel;
}

View File

@ -67,4 +67,9 @@ public class RobotInformationDO extends BaseDO {
*/
private Integer autoCharge;
/**
* 是否自动充电0:手动充电,1:自动充电
*/
private Integer chargeType;
}

View File

@ -45,6 +45,6 @@ public class RobotModelDO extends BaseDO {
/**
* 是否自动充电0:手动充电,1:自动充电
*/
private Integer autoCharge;
private Integer chargeType;
}

View File

@ -0,0 +1,31 @@
package cn.iocoder.yudao.module.system.dal.mysql.robot;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.system.controller.admin.robot.chargelog.RobotChargeLogPageReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotChargeLogDO;
import org.apache.ibatis.annotations.Mapper;
/**
* 车辆充电记录 Mapper
*
* @author 陈宾顺
*/
@Mapper
public interface RobotChargeLogMapper extends BaseMapperX<RobotChargeLogDO> {
default PageResult<RobotChargeLogDO> selectPage(RobotChargeLogPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<RobotChargeLogDO>()
.eqIfPresent(RobotChargeLogDO::getRobotNo, reqVO.getRobotNo())
.eqIfPresent(RobotChargeLogDO::getStartElectricity, reqVO.getStartElectricity())
.eqIfPresent(RobotChargeLogDO::getEndElectricity, reqVO.getEndElectricity())
.betweenIfPresent(RobotChargeLogDO::getEndTime, reqVO.getEndTime())
.eqIfPresent(RobotChargeLogDO::getDeviceNo, reqVO.getDeviceNo())
.betweenIfPresent(RobotChargeLogDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(RobotChargeLogDO::getId));
}
}

View File

@ -10,8 +10,7 @@ import lombok.Getter;
@Getter
@AllArgsConstructor
public enum CommandConfigTypeEnum {
ONE(1), //充电设置(页面)
TWO(2); //充满电周期对应的冲电量
ONE(1); //充电设置(页面)
/**
* 类型
*/

View File

@ -5,7 +5,7 @@ import lombok.Getter;
@Getter
@AllArgsConstructor
public enum DeviceInformationEnum {
public enum DeviceTypeEnum {
CHARGING_STATION(1, "充电桩"),
Conveyor_line(2, "输送线"),

View File

@ -21,7 +21,8 @@ public enum CommandTypeEnum {
WAIT("WAIT","等待"),//等待
GET_PALLET_TOPIC("GET_PALLET_TOPIC","获取托盘位置"),//获取托盘位置
MOVE_TO_PALLET_POSE("MOVE_TO_PALLET_POSE","移动到取货终点"),//让车机移动到取货终点
FORK("FORK","控制货叉上下移动"); //控制货叉上下移动
FORK("FORK","控制货叉上下移动"), //控制货叉上下移动
CHARGE("CHARGE","充电"); //充电(这个充电非下发给车机的指令)
/**
* 类型
*/

View File

@ -12,7 +12,8 @@ public enum RobotStatusEnum {
NO_TASK_STOP(0),//暂停且无任务
STOP(1),//暂停且有处理中的任务
DOING(2), //任务中
STAND_BY(3); //待命
STAND_BY(3), //待命
CHARGE(4); //充电中
/**
* 类型
*/

View File

@ -0,0 +1,19 @@
package cn.iocoder.yudao.module.system.enums.robot.charge;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* robot_charge_log的charge_model 充电模式(1:自动充电2:机会充电3:充满电)
*/
@Getter
@AllArgsConstructor
public enum ChargeModelEnum {
AUTO(1), //自动充电
CHANCE(2), //机会充电
FULL(3); //充满电
/**
* 类型
*/
private final Integer type;
}

View File

@ -0,0 +1,18 @@
package cn.iocoder.yudao.module.system.enums.robot.information;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 下发给车机的类型
*/
@Getter
@AllArgsConstructor
public enum ChargeTypeEnum {
HAND_MOVEMENT(0), //手动充电
AUTOMATIC(1); //自动充电
/**
* 类型
*/
private final Integer type;
}

View File

@ -0,0 +1,22 @@
package cn.iocoder.yudao.module.system.enums.robot.task;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* RobotAcceptTaskDTO的execution_type
*/
@Getter
@AllArgsConstructor
public enum RobotTaksExecutionTypeEnum {
PAUSE("PAUSE"), //停止
CONTINUE("CONTINUE"), //继续
DEFAULT("DEFAULT"), //执行
CANCEL("CANCEL"); //取消
/**
* 类型
*/
private final String type;
}

View File

@ -0,0 +1,20 @@
package cn.iocoder.yudao.module.system.enums.robot.task;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* RobotAcceptTaskDTO的order_type
*/
@Getter
@AllArgsConstructor
public enum RobotTaksOrderTypeEnum {
AUTO_MOVE("AUTO_MOVE"), //自动移库任务
TASK("TASK"), //客户下发的任务
AUTO_CHARGE("AUTO_CHARGE"); //自动充电任务
/**
* 类型
*/
private final String type;
}

View File

@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.system.job.robot;
import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
import cn.iocoder.yudao.module.system.enums.redis.RobotCacheLockEnum;
import cn.iocoder.yudao.module.system.service.robot.job.AutoChargeService;
import cn.iocoder.yudao.module.system.service.robot.job.DistributeTasksService;
import cn.iocoder.yudao.module.system.service.robot.job.RobotTaskAutoMoveService;
import cn.iocoder.yudao.module.system.util.redis.RedissonUtils;
@ -33,6 +34,9 @@ public class RobotJob {
@Autowired
private RobotTaskAutoMoveService robotTaskAutoMoveService;
@Autowired
private AutoChargeService autoChargeService;
//下发任务给车机
@XxlJob("DistributeTasksJob")
@TenantJob
@ -76,4 +80,13 @@ public class RobotJob {
}
}
//下发自动移库任务
@XxlJob("AutoChargeJob")
@TenantJob
public void AutoChargeJob() {
log.info("----下发自动充电任务----");
autoChargeService.autoChargeJob();
}
}

View File

@ -73,6 +73,7 @@ public class RobotInformationServiceImpl implements RobotInformationService {
RobotModelDO robotModelDO = modelMapper.selectById(createReqVO.getRobotModelId());
createReqVO.setRobotModelNumber(robotModelDO.getRobotModelNumber());
createReqVO.setUrl(robotModelDO.getUrl());
createReqVO.setChargeType(robotModelDO.getChargeType());
// 插入
RobotInformationDO information = BeanUtils.toBean(createReqVO, RobotInformationDO.class);
informationMapper.insert(information);

View File

@ -0,0 +1,56 @@
package cn.iocoder.yudao.module.system.service.robot.chargelog;
import java.util.*;
import javax.validation.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.module.system.controller.admin.robot.chargelog.RobotChargeLogPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.chargelog.RobotChargeLogSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotChargeLogDO;
/**
* 车辆充电记录 Service 接口
*
* @author 陈宾顺
*/
public interface RobotChargeLogService {
/**
* 创建车辆充电记录
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createChargeLog(@Valid RobotChargeLogSaveReqVO createReqVO);
/**
* 更新车辆充电记录
*
* @param updateReqVO 更新信息
*/
void updateChargeLog(@Valid RobotChargeLogSaveReqVO updateReqVO);
/**
* 删除车辆充电记录
*
* @param id 编号
*/
void deleteChargeLog(Long id);
/**
* 获得车辆充电记录
*
* @param id 编号
* @return 车辆充电记录
*/
RobotChargeLogDO getChargeLog(Long id);
/**
* 获得车辆充电记录分页
*
* @param pageReqVO 分页查询
* @return 车辆充电记录分页
*/
PageResult<RobotChargeLogDO> getChargeLogPage(RobotChargeLogPageReqVO pageReqVO);
}

View File

@ -0,0 +1,74 @@
package cn.iocoder.yudao.module.system.service.robot.chargelog;
import cn.iocoder.yudao.module.system.controller.admin.robot.chargelog.*;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotChargeLogDO;
import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotChargeLogMapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.CHARGE_LOG_NOT_EXISTS;
/**
* 车辆充电记录 Service 实现类
*
* @author 陈宾顺
*/
@Service
@Validated
public class RobotChargeLogServiceImpl implements RobotChargeLogService {
@Resource
private RobotChargeLogMapper chargeLogMapper;
@Override
public Long createChargeLog(RobotChargeLogSaveReqVO createReqVO) {
// 插入
RobotChargeLogDO chargeLog = BeanUtils.toBean(createReqVO, RobotChargeLogDO.class);
chargeLogMapper.insert(chargeLog);
// 返回
return chargeLog.getId();
}
@Override
public void updateChargeLog(RobotChargeLogSaveReqVO updateReqVO) {
// 校验存在
validateChargeLogExists(updateReqVO.getId());
// 更新
RobotChargeLogDO updateObj = BeanUtils.toBean(updateReqVO, RobotChargeLogDO.class);
chargeLogMapper.updateById(updateObj);
}
@Override
public void deleteChargeLog(Long id) {
// 校验存在
validateChargeLogExists(id);
// 删除
chargeLogMapper.deleteById(id);
}
private void validateChargeLogExists(Long id) {
if (chargeLogMapper.selectById(id) == null) {
throw exception(CHARGE_LOG_NOT_EXISTS);
}
}
@Override
public RobotChargeLogDO getChargeLog(Long id) {
return chargeLogMapper.selectById(id);
}
@Override
public PageResult<RobotChargeLogDO> getChargeLogPage(RobotChargeLogPageReqVO pageReqVO) {
return chargeLogMapper.selectPage(pageReqVO);
}
}

View File

@ -0,0 +1,5 @@
package cn.iocoder.yudao.module.system.service.robot.job;
public interface AutoChargeService {
void autoChargeJob();
}

View File

@ -0,0 +1,44 @@
package cn.iocoder.yudao.module.system.service.robot.job;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.module.system.controller.admin.config.vo.CommonConfigVO;
import cn.iocoder.yudao.module.system.dal.dataobject.config.CommonConfigDO;
import cn.iocoder.yudao.module.system.dal.mysql.config.CommonConfigMapper;
import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotInformationMapper;
import cn.iocoder.yudao.module.system.enums.config.CommandConfigTypeEnum;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import static cn.iocoder.yudao.module.system.config.SystemJobConfiguration.NOTIFY_THREAD_POOL_TASK_EXECUTOR;
@Service
@Slf4j
public class AutoChargeServiceImpl implements AutoChargeService {
@Resource
private RobotInformationMapper informationMapper;
@Resource
private CommonConfigMapper configMapper;
@Override
public void autoChargeJob() {
CommonConfigDO commonConfigDO = configMapper.selectOne(new LambdaQueryWrapper<CommonConfigDO>()
.eq(CommonConfigDO::getConfigType, CommandConfigTypeEnum.ONE.getType()));
if (ObjectUtil.isEmpty(commonConfigDO)) {
log.info("暂未配置充电信息");
return;
}
CommonConfigVO robotStatusData = JSON.parseObject(commonConfigDO.getConfigStr() , CommonConfigVO.class);
}
}

View File

@ -1,25 +1,34 @@
package cn.iocoder.yudao.module.system.service.robot.job;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.module.mqtt.api.task.RobotTaskApi;
import cn.iocoder.yudao.module.mqtt.api.task.dto.Pose2ds;
import cn.iocoder.yudao.module.mqtt.api.task.dto.RobotAcceptTaskDTO;
import cn.iocoder.yudao.module.mqtt.api.task.dto.RobotAcceptTaskData;
import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDataPoseDTO;
import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant;
import cn.iocoder.yudao.module.system.controller.admin.config.vo.CommonConfigVO;
import cn.iocoder.yudao.module.system.dal.dataobject.config.CommonConfigDO;
import cn.iocoder.yudao.module.system.dal.dataobject.houselocation.WareHouseLocationDO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotInformationDO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDetailDO;
import cn.iocoder.yudao.module.system.dal.mysql.config.CommonConfigMapper;
import cn.iocoder.yudao.module.system.dal.mysql.houselocation.WareHouseLocationMapper;
import cn.iocoder.yudao.module.system.dal.mysql.positionmap.PositionMapItemMapper;
import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotInformationMapper;
import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotTaskDetailMapper;
import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotTaskMapper;
import cn.iocoder.yudao.module.system.enums.config.CommandConfigTypeEnum;
import cn.iocoder.yudao.module.system.enums.robot.*;
import cn.iocoder.yudao.module.system.enums.robot.charge.ChargeModelEnum;
import cn.iocoder.yudao.module.system.enums.robot.information.ChargeTypeEnum;
import cn.iocoder.yudao.module.system.util.redis.RedisUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
@ -71,6 +80,12 @@ public class DistributeTasksServiceImpl implements DistributeTasksService {
@Value("${zn.move_height:0.1}")
private double moveHeight;
@Value("${zn.full_electricity:100}")
private String fullElectricity;
@Resource
private CommonConfigMapper configMapper;
@Resource
private WareHouseLocationMapper locationMapper;
@ -116,7 +131,7 @@ public class DistributeTasksServiceImpl implements DistributeTasksService {
Pair<List<RobotInformationDO>, List<RobotTaskDetailDO>> pair = Pair.of(new ArrayList<>(), new ArrayList<>());
TenantContextHolder.setTenantId(1L);
List<RobotInformationDO> robots = robotInformationMapper.selectList(new LambdaQueryWrapperX<RobotInformationDO>()
.eq(RobotInformationDO::getRobotStatus, (RobotStatusEnum.STAND_BY.getType()))
.in(RobotInformationDO::getRobotStatus, RobotStatusEnum.STAND_BY.getType(),RobotStatusEnum.CHARGE.getType())
.eq(RobotInformationDO::getRobotTaskModel, RobotTaskModelEnum.NORMAL.getType())
.orderByDesc(RobotInformationDO::getUpdateTime));
@ -125,6 +140,9 @@ public class DistributeTasksServiceImpl implements DistributeTasksService {
return pair;
}
CommonConfigDO commonConfigDO = configMapper.selectOne(new LambdaQueryWrapper<CommonConfigDO>()
.eq(CommonConfigDO::getConfigType, CommandConfigTypeEnum.ONE.getType()));
for (RobotInformationDO robot : robots) {
String taskStatusKey = RobotTaskChcheConstant.ROBOT_TASK_STATUS +robot.getMacAddress();
String cargoDetectedKey = RobotTaskChcheConstant.ROBOT_CARGO_DETECTED +robot.getMacAddress();
@ -137,6 +155,12 @@ public class DistributeTasksServiceImpl implements DistributeTasksService {
Object cargoDetected = redisUtil.get(cargoDetectedKey);
if (ObjectUtil.isEmpty(cargoDetected) || CARGO_DETECTED.equals(cargoDetected)) {
robot.setRobotStatus(RobotStatusEnum.DOING.getType());
continue;
}
//手动充电的机器人状态是待命
if (ChargeTypeEnum.AUTOMATIC.getType().equals(robot.getChargeType())
&& RobotStatusEnum.CHARGE.getType().equals(robot.getRobotStatus())) {
setRobotStatus(commonConfigDO,robot);
}
}
@ -170,6 +194,48 @@ public class DistributeTasksServiceImpl implements DistributeTasksService {
return ImmutablePair.of(robots, taskDetailDOS);
}
/**
* 设置机器人的状态
* @param commonConfigDO
* @param robot
*/
private void setRobotStatus(CommonConfigDO commonConfigDO, RobotInformationDO robot) {
String pose2dKey = RobotTaskChcheConstant.ROBOT_POSE_BAT +robot.getMacAddress();
String chargeModelKey = RobotTaskChcheConstant.ROBOT_CHARGE_MODEL +robot.getMacAddress();
Object chargeModelCache = redisUtil.get(chargeModelKey);
Object poseCache = redisUtil.get(pose2dKey);
RobotStatusDataPoseDTO dataPoseDTO= JSON.parseObject((String)poseCache, RobotStatusDataPoseDTO.class);
log.info("机器人编号:{} ,信息: {}",robot.getRobotNo(),JSON.toJSONString(dataPoseDTO));
if (ObjectUtil.isEmpty(commonConfigDO) || ObjectUtil.isEmpty(pose2dKey) ) {
return;
}
CommonConfigVO chargeConfig= JSON.parseObject(commonConfigDO.getConfigStr(), CommonConfigVO.class);
//车子剩余电量
BigDecimal batSoc = new BigDecimal(dataPoseDTO.getBat_soc());
BigDecimal oneHundred = new BigDecimal("100");
BigDecimal robotRemainingElectricity = batSoc.multiply(oneHundred);
//设置离开的电量
BigDecimal robotEndElectricity = null;
if (ObjectUtil.isNotEmpty(robot.getAutoCharge()) && ObjectUtil.isNotEmpty(chargeModelCache)
&& !ChargeModelEnum.FULL.getType().equals((Integer) chargeModelCache)) {
robotEndElectricity = new BigDecimal(String.valueOf(robot.getAutoCharge()));
} else if (ObjectUtil.isNotEmpty(chargeModelCache) && ChargeModelEnum.FULL.getType().equals((Integer) chargeModelCache)) {
robotEndElectricity = new BigDecimal(fullElectricity);
} else if (ObjectUtil.isNotEmpty(chargeModelCache) && ChargeModelEnum.CHANCE.getType().equals((Integer) chargeModelCache)) {
robotEndElectricity = new BigDecimal(String.valueOf(chargeConfig.getChanceChargeEnd()));
} else {
robotEndElectricity = new BigDecimal(String.valueOf(chargeConfig.getEndAutoCharge()));
}
if (robotRemainingElectricity.compareTo(robotEndElectricity) >= 0) {
robot.setRobotStatus(RobotStatusEnum.STAND_BY.getType());
}
}
/**
* 获取明细
* @param montageTaskIds

View File

@ -0,0 +1,9 @@
package cn.iocoder.yudao.module.system.service.robot.job;
public interface RobotCommonTaskService {
/**
* 让机器人自动充电
* @param robotNo
*/
public void startAutoCharge(String robotNo) ;
}

View File

@ -0,0 +1,25 @@
package cn.iocoder.yudao.module.system.service.robot.job;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import static cn.iocoder.yudao.module.system.config.SystemJobConfiguration.NOTIFY_THREAD_POOL_TASK_EXECUTOR;
@Service
@Slf4j
public class RobotCommonTaskServiceImpl implements RobotCommonTaskService {
/**
* 让机器人自动充电
* @param robotNo
*/
@Override
@Async(NOTIFY_THREAD_POOL_TASK_EXECUTOR)
public void startAutoCharge(String robotNo) {
//todo 后续沟通下手动模式的需不需要自动充电
}
}

View File

@ -227,5 +227,6 @@ zn:
lift_height: 0.1 #抬高托盘高度
move_height: 0.1 #行走高度
lane_auto_move: true #线库是否自动移库 true:线库执行自动移库 、false线库关闭执行自动移库
robot_position_cache_time: 600 #机器人上报点位存储时间
cycle_do_auto_move: true #存在循环的任务,是否开启自动移库. true:存在循环任务,开启自动移库; false有循环任务不自动移库
robot_position_cache_time: 10 #机器人上报点位存储时间
cycle_do_auto_move: true #存在循环的任务,是否开启自动移库. true:存在循环任务,开启自动移库; false有循环任务不自动移库
full_electricity: 100 #机器人充满电的电量

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.yudao.module.system.dal.mysql.robot.RobotChargeLogMapper">
<!--
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
文档可见https://www.iocoder.cn/MyBatis/x-plugins/
-->
</mapper>