From 99c7a3ab87ae687203f5c7c2e126f23dcbc79371 Mon Sep 17 00:00:00 2001 From: rqian <1206436827@qq.com> Date: Tue, 3 Nov 2026 16:06:58 +0800 Subject: [PATCH] =?UTF-8?q?#=E5=8C=BA=E5=9F=9F=E8=BF=9E=E7=BB=AD=E4=BD=9C?= =?UTF-8?q?=E4=B8=9A=E7=9B=B8=E5=85=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/SiteMapInfoController.java | 1 + .../java/com/maibu/config/DeviceTask.java | 24 +++--- .../java/com/maibu/constant/Constant.java | 2 +- .../com/maibu/constant/FastBeeConstant.java | 5 ++ .../business/RegionConsecutiveTaskRecord.java | 41 ++++++++++ .../core/business/device/NettyDevice.java | 22 +++++ .../core/business/dto/ConsecutiveTaskDTO.java | 20 +++++ .../core/business/dto/DeviceMapPushDTO.java | 2 +- .../core/domain/map/TempObstaclePoint.java | 12 ++- .../core/host/ObstacleDetectionData.java | 5 +- .../com/maibu/core/host/VehicleMessage.java | 7 +- .../RegionConsecutiveTaskRecordMapper.java | 14 ++++ .../java/com/maibu/memory/GlobalMemory.java | 40 ++++----- .../java/com/maibu/memory/SiteMemory.java | 42 ++++++++++ .../com/maibu/mqtt/HostMessageHandler.java | 15 +++- .../main/java/com/maibu/mqtt/MqttTopic.java | 3 + .../controller/DeviceTaskController.java | 81 +++++++++++++++++++ .../main/java/com/maibu/init/InitThread.java | 8 ++ .../com/maibu/service/DeviceTaskService.java | 55 ++++++++++++- .../maibu/service/DeviceThreadService.java | 58 ++++++++++++- .../maibu/controller/DeviceController.java | 10 +++ .../dto/DeviceRunningStatisticsQueryDTO.java | 21 +++++ .../com/maibu/service/IDeviceService.java | 4 + .../maibu/service/impl/DeviceServiceImpl.java | 29 +++++++ 24 files changed, 480 insertions(+), 41 deletions(-) create mode 100644 maibu-common/src/main/java/com/maibu/core/business/RegionConsecutiveTaskRecord.java create mode 100644 maibu-common/src/main/java/com/maibu/core/business/dto/ConsecutiveTaskDTO.java create mode 100644 maibu-common/src/main/java/com/maibu/mapper/RegionConsecutiveTaskRecordMapper.java create mode 100644 maibu-service/maibu-iot-service/src/main/java/com/maibu/dto/DeviceRunningStatisticsQueryDTO.java diff --git a/maibu-admin/src/main/java/com/maibu/web/controller/system/SiteMapInfoController.java b/maibu-admin/src/main/java/com/maibu/web/controller/system/SiteMapInfoController.java index 4a82f88..7232de1 100644 --- a/maibu-admin/src/main/java/com/maibu/web/controller/system/SiteMapInfoController.java +++ b/maibu-admin/src/main/java/com/maibu/web/controller/system/SiteMapInfoController.java @@ -63,5 +63,6 @@ public class SiteMapInfoController extends BaseController { return AjaxResult.error("查询组织下所有场站出错", e.getMessage()); } } + } diff --git a/maibu-common/src/main/java/com/maibu/config/DeviceTask.java b/maibu-common/src/main/java/com/maibu/config/DeviceTask.java index 53b0b63..d94a124 100644 --- a/maibu-common/src/main/java/com/maibu/config/DeviceTask.java +++ b/maibu-common/src/main/java/com/maibu/config/DeviceTask.java @@ -30,37 +30,37 @@ public class DeviceTask { private int keepAlive; - /*设备状态池*/ + /* 设备状态池 */ @Bean(FastBeeConstant.TASK.DEVICE_STATUS_TASK) public Executor deviceStatusTaskExecutor() { return builder(FastBeeConstant.TASK.DEVICE_STATUS_TASK); } - /*平台自动获取线程池(例如定时获取设备信息)*/ + /* 平台自动获取线程池(例如定时获取设备信息) */ @Bean(FastBeeConstant.TASK.DEVICE_FETCH_PROP_TASK) public Executor deviceFetchTaskExecutor() { return builder(FastBeeConstant.TASK.DEVICE_FETCH_PROP_TASK); } - /*设备回调信息(下发指令(服务)设备应答信息)*/ + /* 设备回调信息(下发指令(服务)设备应答信息) */ @Bean(FastBeeConstant.TASK.DEVICE_REPLY_MESSAGE_TASK) public Executor deviceReplyTaskExecutor() { return builder(FastBeeConstant.TASK.DEVICE_REPLY_MESSAGE_TASK); } - /*设备主动上报(设备数据有变化主动上报)*/ + /* 设备主动上报(设备数据有变化主动上报) */ @Bean(FastBeeConstant.TASK.DEVICE_UP_MESSAGE_TASK) public Executor deviceUpMessageTaskExecutor() { return builder(FastBeeConstant.TASK.DEVICE_UP_MESSAGE_TASK); } - /*指令下发(服务下发)*/ + /* 指令下发(服务下发) */ @Bean(FastBeeConstant.TASK.FUNCTION_INVOKE_TASK) public Executor functionInvokeTaskExecutor() { return builder(FastBeeConstant.TASK.FUNCTION_INVOKE_TASK); } - /*内部消费线程*/ + /* 内部消费线程 */ @Bean(FastBeeConstant.TASK.MESSAGE_CONSUME_TASK) public Executor messageConsumeTaskExecutor() { return builder(FastBeeConstant.TASK.MESSAGE_CONSUME_TASK); @@ -81,7 +81,7 @@ public class DeviceTask { return builder(FastBeeConstant.TASK.DELAY_UPGRADE_TASK); } - /*设备其他消息处理*/ + /* 设备其他消息处理 */ @Bean(FastBeeConstant.TASK.DEVICE_OTHER_TASK) public Executor deviceOtherTaskExecutor() { return builder(FastBeeConstant.TASK.DEVICE_OTHER_TASK); @@ -107,6 +107,11 @@ public class DeviceTask { return builder(FastBeeConstant.TASK.AUTO_RULE); } + @Bean(FastBeeConstant.TASK.REGION_CONSECUTIVE_TASK) + public Executor regionConsecutiveTask() { + return builder(FastBeeConstant.TASK.REGION_CONSECUTIVE_TASK); + } + @Bean(FastBeeConstant.TASK.MAP_MESSAGE_PUSH) public Executor mapMessagePush() { return builder(FastBeeConstant.TASK.MAP_MESSAGE_PUSH); @@ -122,8 +127,7 @@ public class DeviceTask { return builder(FastBeeConstant.TASK.COMMON_DEVICE_MONITOR); } - - /*组装线程池*/ + /* 组装线程池 */ private ThreadPoolTaskExecutor builder(String threadNamePrefix) { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(coreSize); @@ -132,7 +136,7 @@ public class DeviceTask { executor.setQueueCapacity(queueCapacity); // 线程池对拒绝任务的处理策略 executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy()); - //线程池名的前缀 + // 线程池名的前缀 executor.setThreadNamePrefix(threadNamePrefix); executor.initialize(); return executor; diff --git a/maibu-common/src/main/java/com/maibu/constant/Constant.java b/maibu-common/src/main/java/com/maibu/constant/Constant.java index 0d1f154..a416705 100644 --- a/maibu-common/src/main/java/com/maibu/constant/Constant.java +++ b/maibu-common/src/main/java/com/maibu/constant/Constant.java @@ -30,7 +30,7 @@ public class Constant { public static final Long hostOfflineInterval = 10000L; // 单位毫秒 // ==================== 远程控制 ==================== - public static final String protocol_version = "1.4.3"; + public static final String protocol_version = "1.4.5"; public static final String remote_control_msg_prefix = "remote-msg"; public static final String remote_control_cmd_prefix = "remote-cmd"; } diff --git a/maibu-common/src/main/java/com/maibu/constant/FastBeeConstant.java b/maibu-common/src/main/java/com/maibu/constant/FastBeeConstant.java index b49b481..3131a36 100644 --- a/maibu-common/src/main/java/com/maibu/constant/FastBeeConstant.java +++ b/maibu-common/src/main/java/com/maibu/constant/FastBeeConstant.java @@ -115,6 +115,11 @@ public interface FastBeeConstant { */ String AUTO_RULE = "autoRule"; + /** + * 区域连续任务处理 + */ + String REGION_CONSECUTIVE_TASK = "regionConsecutiveTaskHandler"; + /** * 设备任务处理线程 */ diff --git a/maibu-common/src/main/java/com/maibu/core/business/RegionConsecutiveTaskRecord.java b/maibu-common/src/main/java/com/maibu/core/business/RegionConsecutiveTaskRecord.java new file mode 100644 index 0000000..4ff4fe5 --- /dev/null +++ b/maibu-common/src/main/java/com/maibu/core/business/RegionConsecutiveTaskRecord.java @@ -0,0 +1,41 @@ +package com.maibu.core.business; + +import java.util.List; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.maibu.core.domain.OrgNoUserDO; +import com.maibu.core.enums.DeviceTaskStaus; +import com.maibu.utils.LongListTypeHandler; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +@TableName("iot_region_consecutive_task_record") +public class RegionConsecutiveTaskRecord extends OrgNoUserDO { + + @TableId(type = IdType.AUTO) + private Long id; + + private String deviceId; + + private Long regionId; + + @TableField(exist = false) + private String deviceAlias; // 别名 + + @TableField(typeHandler = LongListTypeHandler.class) + private List routeIds; // 线路id + + @TableField(typeHandler = LongListTypeHandler.class) + private List taskIds; // 线路id + + private DeviceTaskStaus taskStatus; // 任务状态 + + private int currentIndex; // 当前执行到哪一个 + +} diff --git a/maibu-common/src/main/java/com/maibu/core/business/device/NettyDevice.java b/maibu-common/src/main/java/com/maibu/core/business/device/NettyDevice.java index c2bcd63..7621edb 100644 --- a/maibu-common/src/main/java/com/maibu/core/business/device/NettyDevice.java +++ b/maibu-common/src/main/java/com/maibu/core/business/device/NettyDevice.java @@ -13,6 +13,7 @@ import com.maibu.core.host.MutiPointEntity; import com.maibu.core.host.PointEntity; import com.maibu.core.ota.DeviceOtaFirmware; import com.maibu.mapper.DevicePlanTaskMapper; +import com.maibu.mapper.RegionConsecutiveTaskRecordMapper; import com.maibu.mapper.WorkRecordMapper; import com.maibu.memory.GlobalMemory; import com.maibu.memory.SiteMemory; @@ -68,6 +69,10 @@ public class NettyDevice extends Connector { @JsonIgnore private DevicePlanTaskMapper devicePlanTaskMapper = SpringUtils.getBean(DevicePlanTaskMapper.class); + @JsonIgnore + private RegionConsecutiveTaskRecordMapper regionConsecutiveTaskRecordMapper = SpringUtils + .getBean(RegionConsecutiveTaskRecordMapper.class); + @JsonIgnore private WorkRecordMapper workRecordMapper = SpringUtils.getBean(WorkRecordMapper.class); @@ -128,6 +133,23 @@ public class NettyDevice extends Connector { task.setFinishTime(LocalDateTime.now()); devicePlanTaskMapper.saveOrUpdate(task); SiteMemory siteMemory = GlobalMemory.getSiteMemory(task.getOrgId(), task.getSiteId()); + + // 更新当前任务的执行索引 + RegionConsecutiveTaskRecord record = siteMemory.getRegionConsecutiveTask(device.getSerialNumber()); + if (record != null && DeviceTaskStaus.EXECUTING.equals(record.getTaskStatus())) { + int maxIndex = record.getRouteIds().size() - 1; + int currentIndex = record.getCurrentIndex(); + record.setUpdateTime(LocalDateTime.now()); + if (currentIndex >= maxIndex) { + record.setTaskStatus(DeviceTaskStaus.FINISH); + siteMemory.removeRegionConsecutiveTask(device.getSerialNumber()); + } else { + record.setCurrentIndex(currentIndex + 1); + } + regionConsecutiveTaskRecordMapper.saveOrUpdate(record); + } + + siteMemory.removeDevicePlanExecute(task.getDeviceId()); GlobalMemory.taskPathMap.remove(task.getId()); task = null; diff --git a/maibu-common/src/main/java/com/maibu/core/business/dto/ConsecutiveTaskDTO.java b/maibu-common/src/main/java/com/maibu/core/business/dto/ConsecutiveTaskDTO.java new file mode 100644 index 0000000..7036e89 --- /dev/null +++ b/maibu-common/src/main/java/com/maibu/core/business/dto/ConsecutiveTaskDTO.java @@ -0,0 +1,20 @@ +package com.maibu.core.business.dto; + +import java.util.List; + +import lombok.Data; + +@Data +public class ConsecutiveTaskDTO { + + private String deviceId; + + private List routeIds; // 线路id + + private Long orgId; + + private Long siteId; + + private Long regionId; + +} diff --git a/maibu-common/src/main/java/com/maibu/core/business/dto/DeviceMapPushDTO.java b/maibu-common/src/main/java/com/maibu/core/business/dto/DeviceMapPushDTO.java index f1d8bcf..6e0d626 100644 --- a/maibu-common/src/main/java/com/maibu/core/business/dto/DeviceMapPushDTO.java +++ b/maibu-common/src/main/java/com/maibu/core/business/dto/DeviceMapPushDTO.java @@ -15,7 +15,7 @@ public class DeviceMapPushDTO { private double b; // 电量 private boolean ha = false;// hasAlarm 有无告警 - private String cm;// 控制模式 manual_remote|auto + private Integer cm;// 控制模式 manual_remote|auto private String ms; // 运动状态 moving|stopped|blocked diff --git a/maibu-common/src/main/java/com/maibu/core/domain/map/TempObstaclePoint.java b/maibu-common/src/main/java/com/maibu/core/domain/map/TempObstaclePoint.java index 58681d9..1ddc7d3 100644 --- a/maibu-common/src/main/java/com/maibu/core/domain/map/TempObstaclePoint.java +++ b/maibu-common/src/main/java/com/maibu/core/domain/map/TempObstaclePoint.java @@ -7,10 +7,16 @@ import lombok.Data; @Data public class TempObstaclePoint { - private LatAndLngEntity position; - - private Double radius; + private LatAndLngEntity center; private String alias; + private double radius; // 半径 + + private double size_x; // x方向的长度 + + private double size_y; // y方向的长度 + + private String source = "platform"; // 数据来源 默认给平台 + } diff --git a/maibu-common/src/main/java/com/maibu/core/host/ObstacleDetectionData.java b/maibu-common/src/main/java/com/maibu/core/host/ObstacleDetectionData.java index b5cd917..5b8964c 100644 --- a/maibu-common/src/main/java/com/maibu/core/host/ObstacleDetectionData.java +++ b/maibu-common/src/main/java/com/maibu/core/host/ObstacleDetectionData.java @@ -9,7 +9,6 @@ import lombok.Data; @Data public class ObstacleDetectionData { - private MesType mesType; /** @@ -17,6 +16,10 @@ public class ObstacleDetectionData { */ private String fusion_status; + private String fusion_status_code; + + private String fusion_status_reason; + /** * 障碍物检测状态 */ diff --git a/maibu-common/src/main/java/com/maibu/core/host/VehicleMessage.java b/maibu-common/src/main/java/com/maibu/core/host/VehicleMessage.java index 0288169..81430a6 100644 --- a/maibu-common/src/main/java/com/maibu/core/host/VehicleMessage.java +++ b/maibu-common/src/main/java/com/maibu/core/host/VehicleMessage.java @@ -7,6 +7,8 @@ public class VehicleMessage { private String deviceId; + private double cutter_speed;// 割刀实际转速 + private double battery_percentage;// 实时电量百分比 private double battery_voltage;// 实时电压 @@ -15,6 +17,8 @@ public class VehicleMessage { private double left_motor_temperature;// 实时左电机温度 private double right_motor_temperature;// 实时右电机温度 private double main_temperature;// 实时主温度 + + private String mcu_time; // 下位机状态中的 MCU 时间 private double yaw;// 实时航向角度 private double pitch;// 实时俯仰角度 private String heading_status;// 实时航向状态 @@ -31,7 +35,8 @@ public class VehicleMessage { private double left_motor_rpm;// 实时左电机转速 private double right_motor_rpm;// 实时右电机转速 private double roll;// 实时翻滚角度 - private String control_mode;// 遥控器拨杆对应的当前控制模式 + + private Integer control_mode;// 遥控器拨杆对应的当前控制模式 0=无控制|1=本地遥控|2=自动任务|3=远程遥控 private double linear_speed; // 实时线速度 private double angular_speed; // 实时角速度 diff --git a/maibu-common/src/main/java/com/maibu/mapper/RegionConsecutiveTaskRecordMapper.java b/maibu-common/src/main/java/com/maibu/mapper/RegionConsecutiveTaskRecordMapper.java new file mode 100644 index 0000000..9b63a7d --- /dev/null +++ b/maibu-common/src/main/java/com/maibu/mapper/RegionConsecutiveTaskRecordMapper.java @@ -0,0 +1,14 @@ +package com.maibu.mapper; + +import org.springframework.stereotype.Repository; + +import com.maibu.core.business.RegionConsecutiveTaskRecord; +import com.maibu.mybatis.mapper.BaseMapperX; + +/** + * 区域连续任务下发记录 + */ +@Repository +public interface RegionConsecutiveTaskRecordMapper extends BaseMapperX { + +} diff --git a/maibu-common/src/main/java/com/maibu/memory/GlobalMemory.java b/maibu-common/src/main/java/com/maibu/memory/GlobalMemory.java index dc66dc1..103cda2 100644 --- a/maibu-common/src/main/java/com/maibu/memory/GlobalMemory.java +++ b/maibu-common/src/main/java/com/maibu/memory/GlobalMemory.java @@ -29,10 +29,10 @@ public class GlobalMemory { public static InfluxDBUtil influxDBUtil; -// public static MqttClientUtil mqttClientUtil; - - public static CustomMqttDeviceMonitor customMqttDeviceMonitor = null; //这里面包含了 连我们自己的mqtt 和外部的一些设备,自己的用clientId 是固定的 + // public static MqttClientUtil mqttClientUtil; + public static CustomMqttDeviceMonitor customMqttDeviceMonitor = null; // 这里面包含了 连我们自己的mqtt 和外部的一些设备,自己的用clientId + // 是固定的 public static SiteMemory getSiteMemory(Long orgId, Long siteId) { if (orgId != null && siteId != null) { @@ -87,15 +87,16 @@ public class GlobalMemory { } } - public static void initMqttDeviceMonitor(String mqttHostUrl, String mqttClientId, String mqttUsername, String mqttPassword) { + public static void initMqttDeviceMonitor(String mqttHostUrl, String mqttClientId, String mqttUsername, + String mqttPassword) { if (customMqttDeviceMonitor == null) { // 1. 创建 MQTT 监控器和消息处理器 customMqttDeviceMonitor = new CustomMqttDeviceMonitor(); -// customMqttDeviceMonitor.registerHandler(new GenericPropertyMessageHandler()); - customMqttDeviceMonitor.registerHandler(new HostMessageHandler()); //专门处理上位机的 -// customMqttDeviceMonitor.registerHandler(new ActionMessageHandler()); + // customMqttDeviceMonitor.registerHandler(new GenericPropertyMessageHandler()); + customMqttDeviceMonitor.registerHandler(new HostMessageHandler()); // 专门处理上位机的 + // customMqttDeviceMonitor.registerHandler(new ActionMessageHandler()); - //单独注册 对接上位机的 + // 单独注册 对接上位机的 // 注册设备到 MQTT 监控器 CustomMqttDeviceConfig deviceConfig = new CustomMqttDeviceConfig(); deviceConfig.setDeviceKey(mqttClientId); @@ -103,18 +104,19 @@ public class GlobalMemory { deviceConfig.setClientId(mqttClientId); deviceConfig.setUsername(mqttUsername); deviceConfig.setPassword(mqttPassword); - //TODO 添加所有需要订阅的 + // TODO 添加所有需要订阅的 deviceConfig.setSubscribeTopics(Arrays.asList( - MqttTopic.MOWER_HEARTBEAT,//心跳 - MqttTopic.MOWER_WILDCARD_LOCATION,//位置 经纬度 - MqttTopic.MOWER_WILDCARD_TASK_ROUTE, //路径回复 - MqttTopic.MOWER_WILDCARD_TASK_STATUS,//任务状态 - MqttTopic.MOWER_WILDCARD_ERROR,//错误 - MqttTopic.MOWER_WILDCARD_REALTIME, //状态消息 - MqttTopic.MOWER_WILDCARD_TASK_TARGET_REPLY, //路径规划下发回复 - MqttTopic.MOWER_OTA_RESULT_POST - )); - deviceConfig.setHandlerType(Constant.mqttHandleKey); //唯一的 用于处理上位机mqtt的 + MqttTopic.MOWER_HEARTBEAT, // 心跳 + MqttTopic.MOWER_WILDCARD_LOCATION, // 位置 经纬度 + MqttTopic.MOWER_WILDCARD_TASK_ROUTE, // 路径回复 + MqttTopic.MOWER_WILDCARD_TASK_STATUS, // 任务状态 + MqttTopic.MOWER_WILDCARD_ERROR, // 错误 + MqttTopic.MOWER_WILDCARD_REALTIME, // 状态消息 + MqttTopic.MOWER_WILDCARD_TASK_TARGET_REPLY, // 路径规划下发回复 + MqttTopic.MOWER_OTA_RESULT_POST, // 在线升级 + MqttTopic.MOWER_OBSTACLE + )); + deviceConfig.setHandlerType(Constant.mqttHandleKey); // 唯一的 用于处理上位机mqtt的 customMqttDeviceMonitor.registerDevice(deviceConfig); } } diff --git a/maibu-common/src/main/java/com/maibu/memory/SiteMemory.java b/maibu-common/src/main/java/com/maibu/memory/SiteMemory.java index 6dd2d45..456acc8 100644 --- a/maibu-common/src/main/java/com/maibu/memory/SiteMemory.java +++ b/maibu-common/src/main/java/com/maibu/memory/SiteMemory.java @@ -1,12 +1,15 @@ package com.maibu.memory; +import java.util.ArrayDeque; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Queue; import java.util.concurrent.ConcurrentHashMap; import org.apache.commons.lang3.StringUtils; +import org.apache.poi.ss.formula.functions.T; import org.eclipse.paho.client.mqttv3.MqttClient; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; @@ -22,9 +25,12 @@ import com.maibu.core.business.ErrorIdentificationStandard; import com.maibu.core.business.IoTCommonDevice; import com.maibu.core.business.OrderModel; import com.maibu.core.business.Product; +import com.maibu.core.business.RegionConsecutiveTaskRecord; +import com.maibu.core.business.dto.ConsecutiveTaskDTO; import com.maibu.core.business.dto.DeviceMapPushDTO; import com.maibu.core.domain.entity.SysSite; import com.maibu.core.domain.rule.IotAutoRule; +import com.maibu.core.enums.DeviceTaskStaus; import com.maibu.core.enums.ErrorSource; import com.maibu.core.enums.RuleType; import com.maibu.core.host.VehicleMessage; @@ -75,6 +81,34 @@ public class SiteMemory { public static ConcurrentHashMap iotAutoRuleMap = new ConcurrentHashMap<>(); + public static final ConcurrentHashMap regionConsecutiveTaskMap = new ConcurrentHashMap<>(); + + public void saveRegionConsecutiveTask(String deviceId, ConsecutiveTaskDTO dto, String username) { + RegionConsecutiveTaskRecord record = new RegionConsecutiveTaskRecord(); + record.setDeviceId(deviceId); + record.setRegionId(dto.getRegionId()); + record.setRouteIds(dto.getRouteIds()); + record.setCreateBy(username); + record.setOrgId(dto.getOrgId()); + record.setSiteId(dto.getSiteId()); + record.setRouteIds(dto.getRouteIds()); + record.setTaskStatus(DeviceTaskStaus.NEW); + regionConsecutiveTaskMap.put(deviceId, record); + } + + public RegionConsecutiveTaskRecord getRegionConsecutiveTask(String deviceId) { + return regionConsecutiveTaskMap.get(deviceId); + } + + public RegionConsecutiveTaskRecord removeRegionConsecutiveTask(String deviceId) { + RegionConsecutiveTaskRecord record = getRegionConsecutiveTask(deviceId); + if (record != null) { + record.setTaskStatus(DeviceTaskStaus.CANCELED); + } + regionConsecutiveTaskMap.remove(deviceId); + return record; + } + public List getAllIotAutoRule() { return new ArrayList<>(iotAutoRuleMap.values()); } @@ -95,6 +129,14 @@ public class SiteMemory { return new ArrayList<>(vehicleMessageMap.values()); } + public Integer getDeviceControlMode(String deviceId) { + VehicleMessage v = getVehicleMessage(deviceId); + if (v != null) { + return v.getControl_mode(); + } + return null; + } + public VehicleMessage getVehicleMessage(String deviceId) { return vehicleMessageMap.get(deviceId); } diff --git a/maibu-common/src/main/java/com/maibu/mqtt/HostMessageHandler.java b/maibu-common/src/main/java/com/maibu/mqtt/HostMessageHandler.java index d824e1b..80abc9b 100644 --- a/maibu-common/src/main/java/com/maibu/mqtt/HostMessageHandler.java +++ b/maibu-common/src/main/java/com/maibu/mqtt/HostMessageHandler.java @@ -215,7 +215,7 @@ public class HostMessageHandler implements CustomMqttMessageHandler { NettyDevice nettyDevice = deviceSessionManager.getDevice(deviceId); // todo error故障 if (nettyDevice != null) { - if (nettyDevice.getOnlineStatus() == 0) { + if (nettyDevice.getOnlineStatus() == null || nettyDevice.getOnlineStatus() == 0) { status.setValue(DeviceStatusEnum.offline.getCode()); } else { if (nettyDevice.getTask() != null && nettyDevice.getTask().isTaskAccepted()) { @@ -267,6 +267,19 @@ public class HostMessageHandler implements CustomMqttMessageHandler { WebStatusMessageDTO webStatusMessageDTO = new WebStatusMessageDTO(); List transferData = new ArrayList<>(); + + DeviceStatusDetail cutter_speed = new DeviceStatusDetail(); + cutter_speed.setName("cutter_speed"); + cutter_speed.setValue(String.valueOf(vehicleRelTimeDTO.getData().getCutter_speed())); + cutter_speed.setUnit(""); + transferData.add(cutter_speed); + + DeviceStatusDetail mcu_time = new DeviceStatusDetail(); + mcu_time.setName("mcu_time"); + mcu_time.setValue(String.valueOf(vehicleRelTimeDTO.getData().getMcu_time())); + mcu_time.setUnit(""); + transferData.add(mcu_time); + DeviceStatusDetail voltage = new DeviceStatusDetail(); voltage.setName("battery_percentage"); voltage.setValue(String.valueOf(vehicleRelTimeDTO.getData().getBattery_percentage())); diff --git a/maibu-common/src/main/java/com/maibu/mqtt/MqttTopic.java b/maibu-common/src/main/java/com/maibu/mqtt/MqttTopic.java index 8424a57..0b58129 100644 --- a/maibu-common/src/main/java/com/maibu/mqtt/MqttTopic.java +++ b/maibu-common/src/main/java/com/maibu/mqtt/MqttTopic.java @@ -109,6 +109,9 @@ public class MqttTopic { public static final String MOWER_HEARTBEAT = "mower/+/event/heartbeat/post"; + //障碍物 + public static final String MOWER_OBSTACLE = "mower/+/perception/obstacle/post"; + /** * 格式化 Topic 模板,将 %s 替换为设备ID * diff --git a/maibu-netty-server/src/main/java/com/maibu/controller/DeviceTaskController.java b/maibu-netty-server/src/main/java/com/maibu/controller/DeviceTaskController.java index 43dab3a..df4c708 100644 --- a/maibu-netty-server/src/main/java/com/maibu/controller/DeviceTaskController.java +++ b/maibu-netty-server/src/main/java/com/maibu/controller/DeviceTaskController.java @@ -1,6 +1,7 @@ package com.maibu.controller; import java.time.LocalDate; +import java.util.List; import org.apache.commons.lang3.StringUtils; import org.eclipse.paho.client.mqttv3.MqttException; @@ -14,6 +15,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.maibu.core.business.DevicePlan; +import com.maibu.core.business.dto.ConsecutiveTaskDTO; import com.maibu.core.business.dto.DeviceTaskCommandDTO; import com.maibu.core.controller.BaseController; import com.maibu.core.domain.AjaxResult; @@ -121,6 +123,14 @@ public class DeviceTaskController extends BaseController { if (siteMemory.hasTask(deviceId)) { return AjaxResult.error("当前设备存在任务!"); } + Integer mode = siteMemory.getDeviceControlMode(deviceId); + if (mode == null) { + return AjaxResult.error("当前设备模式不存在,无法自动任务!"); + } + if (mode != 2) { + String modeStr = switchMode(mode); + return AjaxResult.error("当前设备模式:" + modeStr + ",无法自动任务!"); + } return AjaxResult.success(deviceTaskService.createDeviceTask(dto, getLoginUser().getUsername())); } @@ -146,6 +156,14 @@ public class DeviceTaskController extends BaseController { if (siteMemory.hasTask(deviceId)) { return AjaxResult.error("当前设备存在任务!"); } + Integer mode = siteMemory.getDeviceControlMode(deviceId); + if (mode == null) { + return AjaxResult.error("当前设备模式不存在,无法自动任务!"); + } + if (mode != 2) { + String modeStr = switchMode(mode); + return AjaxResult.error("当前设备模式:" + modeStr + ",无法自动任务!"); + } return AjaxResult.success(deviceTaskService.createRegionDeviceTask(dto, getLoginUser().getUsername())); } @@ -194,7 +212,70 @@ public class DeviceTaskController extends BaseController { if (siteMemory.hasTask(deviceId)) { return AjaxResult.error("当前设备存在任务!"); } + Integer mode = siteMemory.getDeviceControlMode(deviceId); + if (mode == null) { + return AjaxResult.error("当前设备模式不存在,无法自动任务!"); + } + if (mode != 2) { + String modeStr = switchMode(mode); + return AjaxResult.error("当前设备模式:" + modeStr + ",无法自动任务!"); + } return AjaxResult.success(deviceTaskService.backToRestPoint(dto, getLoginUser().getUsername())); } + @PostMapping("/createConsecutiveTasks") + public AjaxResult createConsecutiveTasks(@RequestBody ConsecutiveTaskDTO dto) { + String deviceId = dto.getDeviceId(); + Long siteId = dto.getSiteId(); + Long orgId = dto.getOrgId(); + if (StringUtils.isEmpty(deviceId)) { + return AjaxResult.error("deviceId为空!"); + } + if (siteId == null) { + return AjaxResult.error("siteId为空!"); + } + if (orgId == null) { + return AjaxResult.error("orgId为空!"); + } + SiteMemory siteMemory = GlobalMemory.getSiteMemory(orgId, siteId); + if (siteMemory.hasTask(deviceId)) { + return AjaxResult.error("当前设备存在任务!"); + } + Integer mode = siteMemory.getDeviceControlMode(deviceId); + if (mode == null) { + return AjaxResult.error("当前设备模式不存在,无法自动任务!"); + } + if (mode != 2) { + String modeStr = switchMode(mode); + return AjaxResult.error("当前设备模式:" + modeStr + ",无法自动任务!"); + } + deviceTaskService.createConsecutiveTasks(dto, getLoginUser().getUsername()); + return AjaxResult.success(); + } + + public String switchMode(Integer mode) { + String modeStr = ""; + switch (mode) { + case 0: + modeStr = "无控制"; + break; + case 1: + modeStr = "本地遥控"; + break; + case 2: + modeStr = "自动任务"; + break; + case 3: + modeStr = "远程遥控"; + break; + } + return modeStr; + } + + @PostMapping("/cancelConsecutiveTask") + public AjaxResult cancelConsecutiveTask(@RequestBody List deviceIds) throws MqttException { + deviceTaskService.cancelConsecutiveTask(deviceIds); + return AjaxResult.success(); + } + } diff --git a/maibu-netty-server/src/main/java/com/maibu/init/InitThread.java b/maibu-netty-server/src/main/java/com/maibu/init/InitThread.java index 2999657..1480876 100644 --- a/maibu-netty-server/src/main/java/com/maibu/init/InitThread.java +++ b/maibu-netty-server/src/main/java/com/maibu/init/InitThread.java @@ -79,6 +79,9 @@ public class InitThread implements ApplicationRunner { @Resource(name = FastBeeConstant.TASK.AUTO_RULE) private Executor autoRuleExecutor; + @Resource(name = FastBeeConstant.TASK.REGION_CONSECUTIVE_TASK) + private Executor regionConsecutiveTasksExecutor; + @Resource(name = FastBeeConstant.TASK.COMMON_DEVICE_MONITOR) private Executor commonDeviceMonitorExecutor; @@ -182,6 +185,11 @@ public class InitThread implements ApplicationRunner { GlobalMemory.initMqttDeviceMonitor(mqttHostUrl, mqttClientId, mqttUsername, mqttPassword); + // 区域连续任务处理线程 + regionConsecutiveTasksExecutor.execute(() -> { + deviceThreadService.regionConsecutiveTaskHandler(); + }); + // 规则触发线程 autoRuleExecutor.execute(() -> { deviceThreadService.autoRule(); diff --git a/maibu-netty-server/src/main/java/com/maibu/service/DeviceTaskService.java b/maibu-netty-server/src/main/java/com/maibu/service/DeviceTaskService.java index 4b262e4..83c1c1f 100644 --- a/maibu-netty-server/src/main/java/com/maibu/service/DeviceTaskService.java +++ b/maibu-netty-server/src/main/java/com/maibu/service/DeviceTaskService.java @@ -9,7 +9,6 @@ import java.util.List; import java.util.Random; import java.util.stream.Collectors; -import com.maibu.memory.DeviceSessionManager; import org.apache.commons.lang3.StringUtils; import org.eclipse.paho.client.mqttv3.MqttException; import org.springframework.beans.factory.annotation.Autowired; @@ -24,8 +23,10 @@ import com.maibu.core.business.Device; import com.maibu.core.business.DevicePlan; import com.maibu.core.business.DevicePlanTask; import com.maibu.core.business.DeviceTaskPlanRule; +import com.maibu.core.business.RegionConsecutiveTaskRecord; import com.maibu.core.business.WorkRecord; import com.maibu.core.business.device.NettyDevice; +import com.maibu.core.business.dto.ConsecutiveTaskDTO; import com.maibu.core.business.dto.DeviceTaskCommandDTO; import com.maibu.core.domain.entity.SysRegion; import com.maibu.core.domain.entity.SysSite; @@ -42,10 +43,11 @@ import com.maibu.exception.ServiceException; import com.maibu.mapper.DeviceMapper; import com.maibu.mapper.DevicePlanMapper; import com.maibu.mapper.DevicePlanTaskMapper; -import com.maibu.mapper.SiteMapInfoMapper; +import com.maibu.mapper.RegionConsecutiveTaskRecordMapper; import com.maibu.mapper.SysRegionMapper; import com.maibu.mapper.SysSiteMapper; import com.maibu.mapper.WorkRecordMapper; +import com.maibu.memory.DeviceSessionManager; import com.maibu.memory.GlobalMemory; import com.maibu.memory.SiteMemory; import com.maibu.utils.MessageUtils; @@ -77,6 +79,9 @@ public class DeviceTaskService { @Autowired private SysRegionMapper sysRegionMapper; + @Autowired + private RegionConsecutiveTaskRecordMapper regionConsecutiveTaskRecordMapper; + private static final ObjectMapper objectMapper = new ObjectMapper(); public int insertOrUpdate(DevicePlan devicePlan, LoginUser loginUser) { @@ -669,4 +674,50 @@ public class DeviceTaskService { return task.getId(); } + public void createConsecutiveTasks(ConsecutiveTaskDTO dto, String username) { + + if (dto.getOrgId() == null) { + SysSite site = sysSiteMapper.selectById(dto.getSiteId()); + if (site != null) { + dto.setOrgId(site.getOrgId()); + } + } + SiteMemory siteMemory = GlobalMemory.getSiteMemory(dto.getOrgId(), dto.getSiteId()); + if (siteMemory == null) { + throw new ServiceException(MessageUtils.message("任务下发出错!")); + } + siteMemory.saveRegionConsecutiveTask(dto.getDeviceId(), dto, username); + + } + + public void cancelConsecutiveTask(List deivceIds) throws MqttException { + if (CollectionUtils.isEmpty(deivceIds)) { + return; + } + List records = new ArrayList<>(); + for (String deviceId : deivceIds) { + NettyDevice device = deviceSessionManager.getDevice(deviceId); + if (device != null && device.getDevice() != null) { + // 取消当前执行的任务 + device.cancelingTask(); + Long orgId = device.getDevice().getOrgId(); + Long siteId = device.getDevice().getSiteId(); + SiteMemory siteMemory = GlobalMemory.getSiteMemory(orgId, siteId); + RegionConsecutiveTaskRecord record = null; + if (siteMemory != null) { + record = siteMemory.removeRegionConsecutiveTask(deviceId); + } + if (record != null) { + record.setUpdateTime(LocalDateTime.now()); + record.setTaskStatus(DeviceTaskStaus.CANCELED); + records.add(record); + + } + } + } + if (!CollectionUtils.isEmpty(records)) { + regionConsecutiveTaskRecordMapper.saveOrUpdateBatch(records); + } + } + } diff --git a/maibu-netty-server/src/main/java/com/maibu/service/DeviceThreadService.java b/maibu-netty-server/src/main/java/com/maibu/service/DeviceThreadService.java index f13652b..601e659 100644 --- a/maibu-netty-server/src/main/java/com/maibu/service/DeviceThreadService.java +++ b/maibu-netty-server/src/main/java/com/maibu/service/DeviceThreadService.java @@ -20,6 +20,8 @@ import com.maibu.core.business.dto.WebMapMessageDTO; import com.maibu.core.business.dto.WebOlineStatusMessageDTO; import com.maibu.core.enums.*; import com.maibu.utils.json.JsonUtils; +import com.maibu.utils.spring.SpringUtils; + import org.apache.commons.lang3.StringUtils; import org.checkerframework.checker.units.qual.s; import org.springframework.beans.factory.annotation.Autowired; @@ -31,6 +33,7 @@ import org.springframework.util.CollectionUtils; import com.alibaba.fastjson2.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.maibu.constant.Constant; import com.maibu.constant.NettyCacheKey; import com.maibu.core.business.Device; @@ -38,6 +41,7 @@ import com.maibu.core.business.DeviceRunStatistics; import com.maibu.core.business.DeviceRunningStatusHistory; import com.maibu.core.business.DeviceStatusRecordDTO; import com.maibu.core.business.ErrorIdentificationStandard; +import com.maibu.core.business.RegionConsecutiveTaskRecord; import com.maibu.core.business.alarm_center.AlarmMessage; import com.maibu.core.business.device.NettyDevice; import com.maibu.core.business.inter.WebsocketMesDispather; @@ -54,6 +58,7 @@ import com.maibu.dto.DeviceTaskStatusMessageDTO; import com.maibu.mapper.DeviceRunStatisticsMapper; import com.maibu.mapper.ErrorIdentificationStandardMapper; import com.maibu.mapper.HostLocationMapper; +import com.maibu.mapper.RegionConsecutiveTaskRecordMapper; import com.maibu.memory.DeviceSessionManager; import com.maibu.memory.GlobalMemory; import com.maibu.memory.SiteMemory; @@ -104,6 +109,9 @@ public class DeviceThreadService { @Autowired private DeviceTaskService deviceTaskService; + @JsonIgnore + private RegionConsecutiveTaskRecordMapper regionConsecutiveTaskRecordMapper; + public void deviceErrorMonitor() throws InterruptedException, IOException { initStandard(); @@ -308,7 +316,8 @@ public class DeviceThreadService { } if (nowTime - lastActiveTime >= Constant.hostOfflineInterval) { // 超时了判断离线 - if (nettyDevice != null && nettyDevice.getOnlineStatus() == 1) { + if (nettyDevice != null && nettyDevice.getOnlineStatus() != null + && nettyDevice.getOnlineStatus() == 1) { nettyDevice.status(DeviceStatus.offline.getType()); // todo 推送设备离线 String key = NettyCacheKey.latestPositonKey + deviceId; @@ -401,7 +410,7 @@ public class DeviceThreadService { } else { Integer lastOnlineStatus = nettyDevice.getOnlineStatus(); - if (lastOnlineStatus == 0) { + if (lastOnlineStatus == null || lastOnlineStatus == 0) { statusChangePush(deviceId, device.getSiteId(), 1); } // todo 推送设备上线 @@ -567,4 +576,49 @@ public class DeviceThreadService { return null; } + /** + * 规则触发自动判断 + */ + public void regionConsecutiveTaskHandler() { + executor.scheduleWithFixedDelay(() -> { + try { + List list = GlobalMemory.getAllSiteMemory(); + if (!CollectionUtils.isEmpty(list)) { + list.forEach(siteMemory -> { + + ConcurrentHashMap recordMap = siteMemory.regionConsecutiveTaskMap; + if (!CollectionUtils.isEmpty(recordMap)) { + recordMap.keySet().forEach(key -> { + RegionConsecutiveTaskRecord record = recordMap.get(key); + if (record == null || record.getDeviceId() == null + || CollectionUtils.isEmpty(record.getRouteIds())) + return; + if (siteMemory.hasTask(record.getDeviceId())) + return; + int currentIndex = record.getCurrentIndex(); + Long routeId = record.getRouteIds().get(currentIndex); + DeviceTaskCommandDTO dto = new DeviceTaskCommandDTO(); + dto.setDeviceId(record.getDeviceId()); + dto.setOrgId(siteMemory.getSysSite().getOrgId()); + dto.setSiteId(siteMemory.getSysSite().getId()); + dto.setRouteId(routeId); + Long taskId = deviceTaskService.createDeviceTask(dto, "system"); + if (taskId != null) { + record.getTaskIds().add(taskId); + record.setCurrentIndex(currentIndex + 1); + + regionConsecutiveTaskRecordMapper.saveOrUpdate(record); + siteMemory.regionConsecutiveTaskMap.put(key, record); + + } + }); + } + }); + } + } catch (Exception e) { + log.error("区域连续任务处理线程错误:{}", e.getMessage()); + } + }, 0, 500, TimeUnit.MILLISECONDS); + } + } diff --git a/maibu-service/maibu-iot-service/src/main/java/com/maibu/controller/DeviceController.java b/maibu-service/maibu-iot-service/src/main/java/com/maibu/controller/DeviceController.java index cf705cf..dd16583 100644 --- a/maibu-service/maibu-iot-service/src/main/java/com/maibu/controller/DeviceController.java +++ b/maibu-service/maibu-iot-service/src/main/java/com/maibu/controller/DeviceController.java @@ -8,6 +8,7 @@ import com.maibu.core.controller.BaseController; import com.maibu.core.domain.AjaxResult; import com.maibu.core.page.TableDataInfo; import com.maibu.dto.DeviceParamAuthDTO; +import com.maibu.dto.DeviceRunningStatisticsQueryDTO; import com.maibu.enums.BusinessType; import com.maibu.mapper.DeviceRunStatisticsMapper; import com.maibu.mybatis.LambdaQueryWrapperX; @@ -306,4 +307,13 @@ public class DeviceController extends BaseController { } + /** + * 查看当前设备有没授权修改参数 + */ + @PostMapping("/runningHistoryStatistics") + public AjaxResult runningHistoryStatistics(@RequestBody DeviceRunningStatisticsQueryDTO dto) { + return AjaxResult.success(deviceService.runningHistoryStatistics(dto)); + } + + } diff --git a/maibu-service/maibu-iot-service/src/main/java/com/maibu/dto/DeviceRunningStatisticsQueryDTO.java b/maibu-service/maibu-iot-service/src/main/java/com/maibu/dto/DeviceRunningStatisticsQueryDTO.java new file mode 100644 index 0000000..d1e3c03 --- /dev/null +++ b/maibu-service/maibu-iot-service/src/main/java/com/maibu/dto/DeviceRunningStatisticsQueryDTO.java @@ -0,0 +1,21 @@ +package com.maibu.dto; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +@Data +public class DeviceRunningStatisticsQueryDTO { + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime startTime; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime endTime; + + private String deviceId; +} diff --git a/maibu-service/maibu-iot-service/src/main/java/com/maibu/service/IDeviceService.java b/maibu-service/maibu-iot-service/src/main/java/com/maibu/service/IDeviceService.java index 2958688..9eff6f6 100644 --- a/maibu-service/maibu-iot-service/src/main/java/com/maibu/service/IDeviceService.java +++ b/maibu-service/maibu-iot-service/src/main/java/com/maibu/service/IDeviceService.java @@ -1,10 +1,12 @@ package com.maibu.service; import com.maibu.core.business.Device; +import com.maibu.core.business.DeviceRunningStatusHistory; import com.maibu.core.business.dto.DeviceBindDTO; import com.maibu.core.domain.AjaxResult; import com.maibu.core.domain.model.LoginUser; import com.maibu.dto.DeviceParamAuthDTO; +import com.maibu.dto.DeviceRunningStatisticsQueryDTO; import java.util.List; @@ -88,4 +90,6 @@ public interface IDeviceService { public boolean hasPermission(String deviceId); + public List runningHistoryStatistics(DeviceRunningStatisticsQueryDTO dto); + } diff --git a/maibu-service/maibu-iot-service/src/main/java/com/maibu/service/impl/DeviceServiceImpl.java b/maibu-service/maibu-iot-service/src/main/java/com/maibu/service/impl/DeviceServiceImpl.java index c5b4bbb..f3f2c68 100644 --- a/maibu-service/maibu-iot-service/src/main/java/com/maibu/service/impl/DeviceServiceImpl.java +++ b/maibu-service/maibu-iot-service/src/main/java/com/maibu/service/impl/DeviceServiceImpl.java @@ -36,6 +36,7 @@ import com.maibu.core.enums.DeviceTaskStaus; import com.maibu.core.host.LocationMessage; import com.maibu.core.redis.RedisCache; import com.maibu.dto.DeviceParamAuthDTO; +import com.maibu.dto.DeviceRunningStatisticsQueryDTO; import com.maibu.mapper.DeviceMapper; import com.maibu.mapper.DevicePlanMapper; import com.maibu.mapper.DeviceStatusHistoryMapper; @@ -445,4 +446,32 @@ public class DeviceServiceImpl implements IDeviceService { return deviceMapper.selectDeviceBySpiltCode(code); } + @Override + public List runningHistoryStatistics(DeviceRunningStatisticsQueryDTO dto) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + if (dto != null && !StringUtils.isEmpty(dto.getDeviceId())) { + queryWrapper.eq(DeviceRunningStatusHistory::getDeviceId, dto.getDeviceId()); + } + if (dto != null && dto.getStartTime() != null && dto.getEndTime() != null) { + queryWrapper.ge(DeviceRunningStatusHistory::getCreateTime, dto.getStartTime()); + queryWrapper.le(DeviceRunningStatusHistory::getCreateTime, dto.getEndTime()); + } + List list = deviceStatusHistoryMapper.selectList(queryWrapper); + + String key = "running_status:" + dto.getDeviceId(); + DeviceStatusRecordDTO recordDTO = redisCache.getCacheObject(key); + List cacheList; + if (recordDTO != null) { + cacheList = recordDTO.getHistories(); + if (!CollectionUtils.isEmpty(list)) { + if (!CollectionUtils.isEmpty(cacheList)) { + list.addAll(cacheList); + } + } else { + return cacheList; + } + } + return list; + } + }