#update
This commit is contained in:
@@ -14,6 +14,7 @@ import org.springframework.data.annotation.Transient;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 设备对象 iot_device
|
||||
@@ -106,7 +107,7 @@ public class Device extends BaseDO {
|
||||
private Integer onlineStatus;
|
||||
|
||||
@TableField(exist = false)
|
||||
private Integer feStatus; //前端大屏显示 1任务中/2空闲/3离线
|
||||
private Integer feStatus; //前端大屏显示 1任务中/2空闲
|
||||
|
||||
/**
|
||||
* wifi信号强度(信号极好4格[-55— 0],信号好3格[-70— -55],信号一般2格[-85— -70],信号差1格[-100— -85])
|
||||
@@ -223,4 +224,7 @@ public class Device extends BaseDO {
|
||||
return lastRunningStatus != null ? lastRunningStatus : new DeviceRunningStatusHistory();
|
||||
}
|
||||
|
||||
@TableField(exist = false)
|
||||
private Map<Integer,Integer> statusStatistics;
|
||||
|
||||
}
|
||||
|
||||
@@ -5,14 +5,19 @@ import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.maibu.core.domain.OrgBaseDO;
|
||||
import com.maibu.core.enums.DeviceTaskStaus;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@TableName(value = "iot_device_plan", autoResultMap = true)
|
||||
public class DevicePlan {
|
||||
public class DevicePlan extends OrgBaseDO {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
@@ -31,25 +36,15 @@ public class DevicePlan {
|
||||
|
||||
private Long routeId; // 线路id
|
||||
|
||||
private Long userId; // 用户id
|
||||
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
private DeviceTaskPlanRule deviceTaskPlanRules; //计划
|
||||
|
||||
private LocalDateTime createTime;
|
||||
|
||||
private String createBy;
|
||||
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
private String updateBy;
|
||||
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime finishTime;
|
||||
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime startTime; //开始时间 时分秒
|
||||
|
||||
private int delFlag = 0; //删除状态 1删除
|
||||
|
||||
@TableField(exist = false)
|
||||
private boolean dayTriggerFlag = false; //当天的任务是否已经生成
|
||||
}
|
||||
|
||||
@@ -4,14 +4,18 @@ 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.BaseDO;
|
||||
import com.maibu.core.domain.OrgBaseDO;
|
||||
import com.maibu.core.enums.DeviceTaskStaus;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@TableName("iot_device_task")
|
||||
public class DevicePlanTask {
|
||||
public class DevicePlanTask extends OrgBaseDO {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
@@ -31,8 +35,6 @@ public class DevicePlanTask {
|
||||
|
||||
private LocalDateTime startTime; //开始时间 时分秒
|
||||
|
||||
private LocalDateTime createTime; //创建时间
|
||||
|
||||
private String taskType; //任务类型分类
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.maibu.core.business;
|
||||
|
||||
import com.maibu.core.business.path.LatAndLngEntity;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class PlanPath {
|
||||
|
||||
private String name;
|
||||
private List<LatAndLngEntity> path;
|
||||
private List<LatAndLngEntity> outer;
|
||||
private String img;
|
||||
private String planModel;
|
||||
|
||||
}
|
||||
@@ -1,15 +1,30 @@
|
||||
package com.maibu.core.business;
|
||||
|
||||
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.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||
import com.maibu.core.domain.OrgBaseDO;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class WorkRecord implements Serializable {
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName(value = "iot_work_record", autoResultMap = true)
|
||||
public class WorkRecord extends OrgBaseDO {
|
||||
private static final long serialVersionUID = 1L;
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
private String workName;
|
||||
private Long userId;
|
||||
private String jsonData;
|
||||
|
||||
// private String jsonData;
|
||||
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
private PlanPath jsonData; //计划
|
||||
|
||||
private String imgUrl;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,26 @@
|
||||
package com.maibu.core.business.device;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.maibu.core.business.DevicePlanTask;
|
||||
import com.maibu.core.business.DeviceRunStatistics;
|
||||
import com.maibu.core.business.PlanPath;
|
||||
import com.maibu.core.business.WorkRecord;
|
||||
import com.maibu.core.business.path.RoutePlanSendEntity;
|
||||
import com.maibu.core.enums.ConnectorType;
|
||||
import com.maibu.core.enums.DeviceTaskStaus;
|
||||
import com.maibu.mapper.DevicePlanTaskMapper;
|
||||
import com.maibu.mapper.WorkRecordMapper;
|
||||
import com.maibu.memory.GlobalMemory;
|
||||
import com.maibu.memory.SiteMemory;
|
||||
import com.maibu.utils.spring.SpringUtils;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import com.maibu.core.business.path.LatAndLngEntity;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
@@ -20,14 +34,24 @@ public class NettyDevice extends Connector {
|
||||
|
||||
private Long currentTaskId; //当前执行的任务;
|
||||
|
||||
private DevicePlanTask task; //当前执行的任务;
|
||||
|
||||
private Integer onlineStatus; //在线状态 0 离线 1在线
|
||||
|
||||
private LatAndLngEntity currentPoint; //执行任务的当前点
|
||||
|
||||
private Queue<LatAndLngEntity> locationQueue = new LinkedList<>();
|
||||
|
||||
private DeviceRunStatistics latestStatus;
|
||||
|
||||
private Long latestLoginTime;
|
||||
|
||||
private boolean executingTask = false;
|
||||
|
||||
private DevicePlanTaskMapper devicePlanTaskMapper = SpringUtils.getBean(DevicePlanTaskMapper.class);
|
||||
|
||||
private WorkRecordMapper workRecordMapper = SpringUtils.getBean(WorkRecordMapper.class);
|
||||
|
||||
public NettyDevice(String connectorId) {
|
||||
super(connectorId);
|
||||
this.deviceType = ConnectorType.MASTER; // 默认上位机角色
|
||||
@@ -38,5 +62,105 @@ public class NettyDevice extends Connector {
|
||||
this.deviceType = deviceType;
|
||||
}
|
||||
|
||||
public void sendNextPoint() {
|
||||
if (task.getTaskStaus().equals(DeviceTaskStaus.PAUSE)) return;
|
||||
if (!locationQueue.isEmpty()) {
|
||||
LatAndLngEntity entity = locationQueue.poll();
|
||||
if (entity != null) {
|
||||
RoutePlanSendEntity routePlanSendEntity = new RoutePlanSendEntity();
|
||||
routePlanSendEntity.setCommandType((byte) 0x01);
|
||||
routePlanSendEntity.setPointCounts((short) 1);
|
||||
routePlanSendEntity.setTargetLatitude(entity.getLat());
|
||||
routePlanSendEntity.setTargetLongitude(entity.getLng());
|
||||
routePlanSendEntity.setSpeed((short) 1000);
|
||||
byte[] bytes = routePlanSendEntity.toBytes();
|
||||
System.out.println("====Lat:" + entity.getLat() + " ====Lng:" + entity.getLng());
|
||||
|
||||
currentPoint = entity;
|
||||
if (this.getChannel() != null && this.getChannel().isActive()) {
|
||||
this.getChannel().writeAndFlush(Unpooled.wrappedBuffer(bytes));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void finishTask() {
|
||||
if (executingTask) {
|
||||
task.setTaskStaus(DeviceTaskStaus.FINISH);
|
||||
task.setFinishTime(LocalDateTime.now());
|
||||
devicePlanTaskMapper.saveOrUpdate(task);
|
||||
SiteMemory siteMemory = GlobalMemory.getSiteMemory(task.getOrgId(), task.getSiteId());
|
||||
siteMemory.removeDevicePlanExecute(task.getDeviceId());
|
||||
task = null;
|
||||
currentTaskId = null;
|
||||
executingTask = false;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized boolean cancelTask() {
|
||||
if (executingTask) {
|
||||
task.setTaskStaus(DeviceTaskStaus.CANCELED);
|
||||
task.setUpdateTime(LocalDateTime.now());
|
||||
devicePlanTaskMapper.saveOrUpdate(task);
|
||||
SiteMemory siteMemory = GlobalMemory.getSiteMemory(task.getOrgId(), task.getSiteId());
|
||||
siteMemory.removeDevicePlanExecute(task.getDeviceId());
|
||||
task = null;
|
||||
currentTaskId = null;
|
||||
locationQueue.clear();
|
||||
executingTask = false;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//todo 优化
|
||||
public synchronized boolean pauseTask() {
|
||||
if (executingTask) {
|
||||
task.setTaskStaus(DeviceTaskStaus.PAUSE);
|
||||
executingTask = false;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//todo 优化
|
||||
public synchronized boolean recoveryTask() {
|
||||
if (!executingTask) {
|
||||
task.setTaskStaus(DeviceTaskStaus.EXECUTING);
|
||||
executingTask = true;
|
||||
sendNextPoint();
|
||||
return true;
|
||||
}else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void startTask() {
|
||||
try {
|
||||
if (executingTask) return;
|
||||
if (task != null) {
|
||||
Long routeId = task.getRouteId();
|
||||
WorkRecord workRecord = workRecordMapper.selectById(routeId);
|
||||
if (workRecord != null) {
|
||||
PlanPath planPath = workRecord.getJsonData();
|
||||
if (planPath != null && !CollectionUtils.isEmpty(planPath.getPath())) {
|
||||
planPath.getPath().forEach(x -> {
|
||||
locationQueue.offer(x);
|
||||
});
|
||||
}
|
||||
}
|
||||
task.setStartTime(LocalDateTime.now());
|
||||
}
|
||||
executingTask = true;
|
||||
sendNextPoint();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ public class BaseDO implements Serializable {
|
||||
/** 逻辑删除 */
|
||||
@ApiModelProperty("逻辑删除")
|
||||
@TableLogic
|
||||
private Boolean delFlag;
|
||||
private Boolean delFlag = false;
|
||||
|
||||
/** 请求参数 */
|
||||
@TableField(exist = false)
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.maibu.core.domain;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 拓展多租户的 BaseDO 基类
|
||||
*
|
||||
* @author fastbee
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public abstract class OrgBaseDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 多租户编号
|
||||
*/
|
||||
private Long orgId;
|
||||
|
||||
private Long siteId;
|
||||
|
||||
private Long userId;
|
||||
|
||||
}
|
||||
@@ -10,6 +10,7 @@ public enum DeviceTaskStaus {
|
||||
NEW("NEW","新建"),
|
||||
EXECUTING("EXECUTING","执行中"),
|
||||
PAUSE("PAUSE","暂停中"),
|
||||
CANCELED("CANCELED","已取消"),
|
||||
FINISH("FINISH","执行成功"),
|
||||
FAILED("FAILED","执行失败");
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.maibu.mapper;
|
||||
|
||||
import com.maibu.core.business.DevicePlan;
|
||||
import com.maibu.mybatis.mapper.BaseMapperX;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* 设备历史状态
|
||||
*/
|
||||
@Repository
|
||||
public interface DevicePlanMapper extends BaseMapperX<DevicePlan> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.maibu.mapper;
|
||||
|
||||
import com.maibu.core.business.DevicePlanTask;
|
||||
import com.maibu.mybatis.mapper.BaseMapperX;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* 设备历史状态
|
||||
*/
|
||||
@Repository
|
||||
public interface DevicePlanTaskMapper extends BaseMapperX<DevicePlanTask> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.maibu.mapper;
|
||||
|
||||
|
||||
import com.maibu.core.business.WorkRecord;
|
||||
import com.maibu.mybatis.mapper.BaseMapperX;
|
||||
|
||||
|
||||
public interface WorkRecordMapper extends BaseMapperX<WorkRecord> {
|
||||
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import lombok.Data;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -35,7 +36,7 @@ public class GlobalMemory {
|
||||
public static ConcurrentHashMap<Long, IoTCommonProduct> productMap = new ConcurrentHashMap<>();
|
||||
|
||||
|
||||
public SiteMemory getSiteMemory(Long orgId, Long siteId) {
|
||||
public static SiteMemory getSiteMemory(Long orgId, Long siteId) {
|
||||
if (orgId != null && siteId != null) {
|
||||
Map<Long, SiteMemory> siteMemories = orgAttrs.get(orgId);
|
||||
if (!CollectionUtils.isEmpty(siteMemories)) {
|
||||
@@ -45,13 +46,23 @@ public class GlobalMemory {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static List<SiteMemory> getAllSiteMemory() {
|
||||
List<SiteMemory> list = new ArrayList<>();
|
||||
orgAttrs.values().forEach(x -> {
|
||||
list.addAll(x.values());
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增场站内存
|
||||
* @param orgId
|
||||
* @param siteId
|
||||
* @param siteMemory
|
||||
*/
|
||||
public void addSiteMemory(Long orgId, Long siteId, SiteMemory siteMemory) {
|
||||
//todo 初始化
|
||||
public static void addSiteMemory(Long orgId, Long siteId, SiteMemory siteMemory) {
|
||||
|
||||
if (orgId != null && siteId != null) {
|
||||
Map<Long, SiteMemory> siteMemories = orgAttrs.get(orgId);
|
||||
if (CollectionUtils.isEmpty(siteMemories)) {
|
||||
@@ -67,7 +78,7 @@ public class GlobalMemory {
|
||||
* @param orgId
|
||||
* @param siteId
|
||||
*/
|
||||
public void removeSiteMemory(Long orgId, Long siteId) {
|
||||
public static void removeSiteMemory(Long orgId, Long siteId) {
|
||||
if (orgId != null && siteId != null) {
|
||||
Map<Long, SiteMemory> siteMemories = orgAttrs.get(orgId);
|
||||
if (!CollectionUtils.isEmpty(siteMemories)) {
|
||||
|
||||
@@ -38,7 +38,6 @@ public class SiteMemory {
|
||||
//key deviceId execute
|
||||
public static ConcurrentHashMap<String, DevicePlanTask> devicePlanTaskExecuteMap = new ConcurrentHashMap<>();
|
||||
|
||||
|
||||
public static void saveDevice(Device device) {
|
||||
deviceMap.put(device.getSerialNumber(), device);
|
||||
}
|
||||
@@ -49,7 +48,7 @@ public class SiteMemory {
|
||||
}
|
||||
}
|
||||
|
||||
public static void addDevicePlan(DevicePlan devicePlan) {
|
||||
public void addDevicePlan(DevicePlan devicePlan) {
|
||||
if (devicePlan != null && !StringUtils.isEmpty(devicePlan.getDeviceId())) {
|
||||
String deviceId = devicePlan.getDeviceId();
|
||||
List<DevicePlan> list = devicePlanMap.get(deviceId);
|
||||
@@ -66,7 +65,7 @@ public class SiteMemory {
|
||||
}
|
||||
|
||||
|
||||
public static void removeDevicePlan(DevicePlan devicePlan) {
|
||||
public void removeDevicePlan(DevicePlan devicePlan) {
|
||||
if (devicePlan != null && !StringUtils.isEmpty(devicePlan.getDeviceId())) {
|
||||
String deviceId = devicePlan.getDeviceId();
|
||||
List<DevicePlan> list = devicePlanMap.get(deviceId);
|
||||
@@ -76,7 +75,7 @@ public class SiteMemory {
|
||||
}
|
||||
}
|
||||
|
||||
public static void addDevicePlanPrepare(DevicePlanTask devicePlanTask) {
|
||||
public void addDevicePlanPrepare(DevicePlanTask devicePlanTask) {
|
||||
if (devicePlanTask != null && !StringUtils.isEmpty(devicePlanTask.getDeviceId())) {
|
||||
String deviceId = devicePlanTask.getDeviceId();
|
||||
List<DevicePlanTask> list = devicePlanTaskPrepareMap.get(deviceId);
|
||||
@@ -88,7 +87,7 @@ public class SiteMemory {
|
||||
}
|
||||
}
|
||||
|
||||
public static void removeDevicePlanPrepare(DevicePlanTask devicePlanTask) {
|
||||
public void removeDevicePlanPrepare(DevicePlanTask devicePlanTask) {
|
||||
if (devicePlanTask != null && !StringUtils.isEmpty(devicePlanTask.getDeviceId())) {
|
||||
String deviceId = devicePlanTask.getDeviceId();
|
||||
List<DevicePlanTask> list = devicePlanTaskPrepareMap.get(deviceId);
|
||||
@@ -99,18 +98,33 @@ public class SiteMemory {
|
||||
}
|
||||
|
||||
|
||||
public static void addDevicePlanExecute(DevicePlanTask devicePlanTask) {
|
||||
public void addDevicePlanExecute(DevicePlanTask devicePlanTask) {
|
||||
if (devicePlanTask != null && !StringUtils.isEmpty(devicePlanTask.getDeviceId())) {
|
||||
String deviceId = devicePlanTask.getDeviceId();
|
||||
devicePlanTaskExecuteMap.put(deviceId, devicePlanTask);
|
||||
}
|
||||
}
|
||||
|
||||
public static void removeDevicePlanExecute(String deviceId) {
|
||||
public void removeDevicePlanExecute(String deviceId) {
|
||||
if (!StringUtils.isEmpty(deviceId)) {
|
||||
devicePlanTaskExecuteMap.remove(deviceId);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasTask(String deviceId) {
|
||||
DevicePlanTask task = devicePlanTaskExecuteMap.get(deviceId);
|
||||
List<DevicePlanTask> list = devicePlanTaskPrepareMap.get(deviceId);
|
||||
return task != null || !CollectionUtils.isEmpty(list);
|
||||
}
|
||||
|
||||
public DevicePlanTask getDeviceExecuteTask(String deviceId) {
|
||||
if (!StringUtils.isEmpty(deviceId)) {
|
||||
return devicePlanTaskExecuteMap.get(deviceId);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user