#update
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package com.maibu.common;
|
||||
|
||||
import com.maibu.core.enums.ConnectionCloseReason;
|
||||
import io.netty.util.AttributeKey;
|
||||
import lombok.Data;
|
||||
|
||||
@@ -8,4 +9,9 @@ public class Constant {
|
||||
|
||||
public static final AttributeKey<String> ATT_DEVICE_ID = AttributeKey.valueOf("deviceId");
|
||||
|
||||
public static final AttributeKey<ConnectionCloseReason> ATT_CLOSE_REASON = AttributeKey.valueOf("closeReason");
|
||||
|
||||
public static final AttributeKey<String> ATT_ORG_ID = AttributeKey.valueOf("orgId");
|
||||
|
||||
public static final AttributeKey<String> ATT_SITE_ID = AttributeKey.valueOf("siteId");
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package com.maibu.controller;
|
||||
import com.maibu.common.CommandConstant;
|
||||
import com.maibu.core.controller.BaseController;
|
||||
import com.maibu.core.domain.AjaxResult;
|
||||
import com.maibu.dto.NettyDevice;
|
||||
import com.maibu.core.business.device.NettyDevice;
|
||||
import com.maibu.dto.ObstacleData;
|
||||
import com.maibu.manager.DeviceSessionManager;
|
||||
import com.maibu.utils.CommandUtils;
|
||||
@@ -11,7 +11,6 @@ import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.util.CharsetUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.java_websocket.WebSocket;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.maibu.controller;
|
||||
|
||||
import com.maibu.core.business.DevicePlan;
|
||||
import com.maibu.core.controller.BaseController;
|
||||
import com.maibu.core.domain.AjaxResult;
|
||||
import com.maibu.core.domain.model.LoginUser;
|
||||
import com.maibu.domain.DevicePlan;
|
||||
import com.maibu.dto.DeviceTaskQueryDTO;
|
||||
import com.maibu.service.DeviceTaskService;
|
||||
import com.maibu.utils.SecurityUtils;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package com.maibu.controller;
|
||||
|
||||
import com.maibu.core.business.DeviceRunningStatusHistory;
|
||||
import com.maibu.core.controller.BaseController;
|
||||
import com.maibu.core.domain.AjaxResult;
|
||||
import com.maibu.core.page.TableDataInfo;
|
||||
import com.maibu.domain.DeviceRunningStatusHistory;
|
||||
import com.maibu.entity.ErrorIdentificationStandard;
|
||||
import com.maibu.core.business.ErrorIdentificationStandard;
|
||||
import com.maibu.service.NettyDeviceService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
package com.maibu.dto;
|
||||
|
||||
import com.maibu.enums.ConnectorStatus;
|
||||
import io.netty.channel.Channel;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
@Data
|
||||
public class Connector {
|
||||
// 获取设备ID
|
||||
private final String connectorId;
|
||||
// 设备ID
|
||||
private ConnectorStatus connectorStatus; // 设备状态(可用、禁言、不可用)
|
||||
// 获取连接的设备列表
|
||||
private Set<Connector> connectedConnectors; // 连接的设备列表 主机绑定从机 从机无绑定
|
||||
|
||||
private Channel channel;
|
||||
|
||||
// 无参构造函数,解决Lombok需要默认构造函数的问题
|
||||
public Connector() {
|
||||
this.connectorId = "";
|
||||
this.connectorStatus = ConnectorStatus.ACTIVE;
|
||||
this.connectedConnectors = new HashSet<>();
|
||||
}
|
||||
|
||||
// 构造器
|
||||
public Connector(String connectorId) {
|
||||
this.connectorId = connectorId;
|
||||
this.connectorStatus = ConnectorStatus.ACTIVE; // 默认状态为完全可用
|
||||
this.connectedConnectors = new HashSet<>();
|
||||
}
|
||||
|
||||
//
|
||||
public void addConnectedDevice(Connector connector) {
|
||||
connectedConnectors.add(connector);
|
||||
}
|
||||
|
||||
// 移除连接的设备,确保双向移除
|
||||
public void removeConnectedDevice(Connector connector) {
|
||||
// 从当前设备的连接列表中移除
|
||||
connectedConnectors.remove(connector);
|
||||
|
||||
}
|
||||
|
||||
public boolean isOnline() {
|
||||
return channel != null && channel.isActive();
|
||||
}
|
||||
|
||||
public boolean canSend() {
|
||||
return connectorStatus == ConnectorStatus.ACTIVE;
|
||||
}
|
||||
|
||||
public boolean canReceive() {
|
||||
return connectorStatus != ConnectorStatus.DISABLED;
|
||||
}
|
||||
|
||||
// 打印设备信息
|
||||
public void printConnectorInfo() {
|
||||
System.out.println("Device ID: " + connectorId);
|
||||
System.out.println("Device Status: " + connectorStatus);
|
||||
System.out.println("Connected Devices: ");
|
||||
for (Connector connectedDevice : connectedConnectors) {
|
||||
System.out.println("- " + connectedDevice.getConnectorId());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.maibu.dto;
|
||||
|
||||
import com.maibu.enums.RespondCode;
|
||||
import com.maibu.core.enums.RespondCode;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.maibu.dto;
|
||||
|
||||
import com.maibu.enums.RespondCode;
|
||||
import com.maibu.core.enums.RespondCode;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.maibu.dto;
|
||||
|
||||
import com.maibu.enums.CommandRequestType;
|
||||
import com.maibu.core.enums.CommandRequestType;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.maibu.dto;
|
||||
|
||||
import com.maibu.enums.RespondCode;
|
||||
import com.maibu.core.enums.RespondCode;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.maibu.dto;
|
||||
|
||||
import com.maibu.enums.DeviceTaskStaus;
|
||||
import com.maibu.core.enums.DeviceTaskStaus;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
package com.maibu.dto;
|
||||
|
||||
|
||||
import com.maibu.domain.DeviceRunStatistics;
|
||||
import com.maibu.entity.path.LatAndLngEntity;
|
||||
import com.maibu.enums.ConnectorType;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class NettyDevice extends Connector {
|
||||
|
||||
private ConnectorType deviceType; // 设备角色类型:MASTER、SLAVE、GENERAL
|
||||
|
||||
private String currentSlaveId;// 当前对应的下位机 master
|
||||
|
||||
private Long currentTaskId; //当前执行的任务;
|
||||
|
||||
private Integer onlineStatus; //在线状态 0 离线 1在线
|
||||
|
||||
private Queue<LatAndLngEntity> locationQueue = new LinkedList<>();
|
||||
|
||||
private DeviceRunStatistics latestStatus;
|
||||
|
||||
private Long latestLoginTime;
|
||||
|
||||
public NettyDevice(String connectorId) {
|
||||
super(connectorId);
|
||||
this.deviceType = ConnectorType.MASTER; // 默认上位机角色
|
||||
}
|
||||
|
||||
public NettyDevice(String connectorId, ConnectorType deviceType) {
|
||||
super(connectorId);
|
||||
this.deviceType = deviceType;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
package com.maibu.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.maibu.enums.CompareEnum;
|
||||
import lombok.Data;
|
||||
import org.springframework.data.annotation.Id;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@Data
|
||||
@TableName("error_identification")
|
||||
public class ErrorIdentificationStandard {
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
private String field;
|
||||
private String compareValues;
|
||||
private CompareEnum compareType;
|
||||
private String errorDescription;
|
||||
private String errorName;
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package com.maibu.entity.path;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class LatAndLngEntity {
|
||||
private double lat;
|
||||
private double lng;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "{" + lat + "," + lng + '}';
|
||||
}
|
||||
}
|
||||
@@ -1,554 +0,0 @@
|
||||
package com.maibu.entity.path;
|
||||
|
||||
|
||||
|
||||
import com.maibu.utils.json.JsonUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
public class MowingPathGenerator {
|
||||
public static final double M_PI = 3.14159265358979323846;
|
||||
public static final double Earth_Radius = 6378137.0;
|
||||
public static final double EPSILON = 1e-6;
|
||||
public static final double REL_EPSILON = 1e-8;
|
||||
public static final double ABS_EPSILON = 1e-12;
|
||||
|
||||
public static class Point {
|
||||
public double x, y;
|
||||
|
||||
public Point(double x, double y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
}
|
||||
|
||||
public static class PathPoint {
|
||||
public double lat, lon;
|
||||
|
||||
public PathPoint(double lat, double lon) {
|
||||
this.lat = lat;
|
||||
this.lon = lon;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Polygon {
|
||||
public Point[] vertices;
|
||||
public int num_vertices;
|
||||
|
||||
public Polygon(Point[] vertices, int num_vertices) {
|
||||
this.vertices = vertices;
|
||||
this.num_vertices = num_vertices;
|
||||
}
|
||||
}
|
||||
|
||||
public static class PolygonWithHoles {
|
||||
public Polygon outer;
|
||||
public Polygon[] holes;
|
||||
public int num_holes;
|
||||
|
||||
public PolygonWithHoles(Polygon outer, Polygon[] holes, int num_holes) {
|
||||
this.outer = outer;
|
||||
this.holes = holes;
|
||||
this.num_holes = num_holes;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ProjectedPoint {
|
||||
public Point pt;
|
||||
public double proj;
|
||||
|
||||
public ProjectedPoint(Point pt, double proj) {
|
||||
this.pt = pt;
|
||||
this.proj = proj;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isEqual(double a, double b) {
|
||||
double diff = Math.abs(a - b);
|
||||
double max_ab = Math.max(Math.abs(a), Math.abs(b));
|
||||
double tolerance = REL_EPSILON * max_ab + ABS_EPSILON;
|
||||
return diff <= tolerance;
|
||||
}
|
||||
|
||||
public static double cross(Point a, Point b) {
|
||||
return a.x * b.y - a.y * b.x;
|
||||
}
|
||||
|
||||
public static boolean getLineIntersection(Point p1, Point p2, Point q1, Point q2, Point intersection) {
|
||||
Point r = new Point(p2.x - p1.x, p2.y - p1.y);
|
||||
Point s = new Point(q2.x - q1.x, q2.y - q1.y);
|
||||
double rxs = cross(r, s);
|
||||
Point qp = new Point(q1.x - p1.x, q1.y - p1.y);
|
||||
double q_p_cross_r = cross(qp, r);
|
||||
|
||||
if (Math.abs(rxs) < EPSILON) {
|
||||
return false;
|
||||
}
|
||||
|
||||
double t = cross(qp, s) / rxs;
|
||||
double u = q_p_cross_r / rxs;
|
||||
|
||||
if (t >= 0.0 - EPSILON && t <= 1.0 + EPSILON && u >= 0.0 - EPSILON && u <= 1.0 + EPSILON) {
|
||||
intersection.x = p1.x + t * r.x;
|
||||
intersection.y = p1.y + t * r.y;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isPointOnSegment(Point pt, Point p1, Point p2) {
|
||||
if (pt.x < Math.min(p1.x, p2.x) - EPSILON || pt.x > Math.max(p1.x, p2.x) + EPSILON) {
|
||||
return false;
|
||||
}
|
||||
if (pt.y < Math.min(p1.y, p2.y) - EPSILON || pt.y > Math.max(p1.y, p2.y) + EPSILON) {
|
||||
return false;
|
||||
}
|
||||
|
||||
double cross = (p2.x - p1.x) * (pt.y - p1.y) - (p2.y - p1.y) * (pt.x - p1.x);
|
||||
if (Math.abs(cross) > EPSILON) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void makeScanline(PolygonWithHoles field, Point lineStart, Point lineEnd, Point normal, double min_proj, Point dir) {
|
||||
double min_x = Double.POSITIVE_INFINITY, max_x = Double.NEGATIVE_INFINITY;
|
||||
double min_y = Double.POSITIVE_INFINITY, max_y = Double.NEGATIVE_INFINITY;
|
||||
|
||||
for (int i = 0; i < field.outer.num_vertices; i++) {
|
||||
Point p = field.outer.vertices[i];
|
||||
if (p.x < min_x) min_x = p.x;
|
||||
if (p.x > max_x) max_x = p.x;
|
||||
if (p.y < min_y) min_y = p.y;
|
||||
if (p.y > max_y) max_y = p.y;
|
||||
}
|
||||
|
||||
double dx = max_x - min_x, dy = max_y - min_y;
|
||||
double len_scan = Math.sqrt(dx * dx + dy * dy) * 1.1;
|
||||
|
||||
Point lineOrigin = new Point(normal.x * min_proj, normal.y * min_proj);
|
||||
|
||||
lineStart.x = lineOrigin.x - dir.x * len_scan;
|
||||
lineStart.y = lineOrigin.y - dir.y * len_scan;
|
||||
|
||||
lineEnd.x = lineOrigin.x + dir.x * len_scan;
|
||||
lineEnd.y = lineOrigin.y + dir.y * len_scan;
|
||||
}
|
||||
|
||||
public static void collectHoleIntersections(PolygonWithHoles poly, Point q1, Point q2, List<ProjectedPoint> intersections, Point dir) {
|
||||
intersections.clear();
|
||||
|
||||
for (int h = 0; h < poly.num_holes; h++) {
|
||||
for (int i = 0; i < poly.holes[h].num_vertices; i++) {
|
||||
Point p1 = poly.holes[h].vertices[i];
|
||||
Point p2 = poly.holes[h].vertices[(i + 1) % poly.holes[h].num_vertices];
|
||||
Point inter = new Point(0, 0);
|
||||
|
||||
if (getLineIntersection(p1, p2, q1, q2, inter)) {
|
||||
double proj = inter.x * dir.x + inter.y * dir.y;
|
||||
intersections.add(new ProjectedPoint(new Point(inter.x, inter.y), proj));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void collectOuterIntersections(PolygonWithHoles poly, Point q1, Point q2, List<ProjectedPoint> intersections, Point dir) {
|
||||
intersections.clear();
|
||||
|
||||
for (int i = 0; i < poly.outer.num_vertices; i++) {
|
||||
Point p1 = poly.outer.vertices[i];
|
||||
Point p2 = poly.outer.vertices[(i + 1) % poly.outer.num_vertices];
|
||||
Point inter = new Point(0, 0);
|
||||
|
||||
if (getLineIntersection(p1, p2, q1, q2, inter)) {
|
||||
double proj = inter.x * dir.x + inter.y * dir.y;
|
||||
intersections.add(new ProjectedPoint(new Point(inter.x, inter.y), proj));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void generateMowingPath(PolygonWithHoles field, double width, Point scanStart, Point scanEnd, List<Point> pathPoints) {
|
||||
pathPoints.clear();
|
||||
|
||||
Point dir = new Point(scanEnd.x - scanStart.x, scanEnd.y - scanStart.y);
|
||||
double len = Math.sqrt(dir.x * dir.x + dir.y * dir.y);
|
||||
dir.x /= len;
|
||||
dir.y /= len;
|
||||
Point normal = new Point(-dir.y, dir.x);
|
||||
|
||||
double min_proj = Double.POSITIVE_INFINITY, max_proj = Double.NEGATIVE_INFINITY;
|
||||
for (int i = 0; i < field.outer.num_vertices; i++) {
|
||||
Point p = field.outer.vertices[i];
|
||||
double proj = p.x * normal.x + p.y * normal.y;
|
||||
if (proj < min_proj) min_proj = proj;
|
||||
if (proj > max_proj) max_proj = proj;
|
||||
}
|
||||
|
||||
int lines = (int) ((max_proj - min_proj) / width + 1);
|
||||
int max_outer_points = lines * field.outer.num_vertices * 2;
|
||||
int max_hole_points = lines * field.num_holes * 10 * 2;
|
||||
|
||||
System.out.printf("dir = (%.4f, %.4f)\n", dir.x, dir.y);
|
||||
System.out.printf("normal = (%.4f, %.4f)\n", normal.x, normal.y);
|
||||
System.out.printf("Projection range: %.4f ~ %.4f (%.4f)\n", min_proj, max_proj, max_proj - min_proj);
|
||||
System.out.printf("lines = %d\n", lines);
|
||||
|
||||
Point lineStart = new Point(0, 0);
|
||||
Point lineEnd = new Point(0, 0);
|
||||
makeScanline(field, lineStart, lineEnd, normal, min_proj, dir);
|
||||
int direction = 1;
|
||||
|
||||
List<List<ProjectedPoint>> outerIntersections = new ArrayList<>();
|
||||
List<List<ProjectedPoint>> holeIntersections = new ArrayList<>();
|
||||
List<Integer> numHole = new ArrayList<>();
|
||||
List<Integer> numOuter = new ArrayList<>();
|
||||
|
||||
for (int l = 0; l < lines; l++) {
|
||||
List<ProjectedPoint> outerInts = new ArrayList<>();
|
||||
collectOuterIntersections(field, lineStart, lineEnd, outerInts, dir);
|
||||
|
||||
List<ProjectedPoint> holeInts = new ArrayList<>();
|
||||
collectHoleIntersections(field, lineStart, lineEnd, holeInts, dir);
|
||||
|
||||
holeInts.sort(Comparator.comparingDouble(p -> p.proj));
|
||||
|
||||
if (direction == -1) {
|
||||
Collections.reverse(holeInts);
|
||||
}
|
||||
|
||||
outerIntersections.add(outerInts);
|
||||
holeIntersections.add(holeInts);
|
||||
numHole.add(holeInts.size());
|
||||
numOuter.add(outerInts.size());
|
||||
|
||||
lineStart.x += normal.x * width;
|
||||
lineStart.y += normal.y * width;
|
||||
lineEnd.x += normal.x * width;
|
||||
lineEnd.y += normal.y * width;
|
||||
direction *= -1;
|
||||
}
|
||||
|
||||
direction = 1;
|
||||
|
||||
for (int l = 0; l < lines; l++) {
|
||||
List<ProjectedPoint> intersections = new ArrayList<>();
|
||||
intersections.addAll(outerIntersections.get(l));
|
||||
intersections.addAll(holeIntersections.get(l));
|
||||
|
||||
intersections.sort(Comparator.comparingDouble(p -> p.proj));
|
||||
|
||||
if (direction == -1) {
|
||||
Collections.reverse(intersections);
|
||||
}
|
||||
|
||||
boolean isHoleStart = false;
|
||||
int layerHoleNum = numHole.get(l);
|
||||
|
||||
if (layerHoleNum > 0) {
|
||||
ProjectedPoint holeStart = holeIntersections.get(l).get(0);
|
||||
ProjectedPoint holeEnd = holeIntersections.get(l).get(layerHoleNum - 1);
|
||||
|
||||
for (int i = 0; i < intersections.size(); i++) {
|
||||
ProjectedPoint testPoint = intersections.get(i);
|
||||
|
||||
if (isEqual(testPoint.proj, holeStart.proj)) {
|
||||
isHoleStart = true;
|
||||
}
|
||||
|
||||
if (isHoleStart) {
|
||||
pathPoints.add(holeStart.pt);
|
||||
|
||||
int holeId = -1;
|
||||
int startIndex = -1, endIndex = -1;
|
||||
boolean isHoleVertices = false;
|
||||
|
||||
for (int h = 0; h < field.num_holes; h++) {
|
||||
Polygon hole = field.holes[h];
|
||||
|
||||
for (int j = 0; j < hole.num_vertices; j++) {
|
||||
Point p1 = hole.vertices[j];
|
||||
Point p2 = hole.vertices[(j + 1) % hole.num_vertices];
|
||||
|
||||
if (isEqual(holeStart.pt.x, p1.x) && isEqual(holeStart.pt.y, p1.y)) {
|
||||
isHoleVertices = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (isPointOnSegment(holeStart.pt, p1, p2)) {
|
||||
holeId = h;
|
||||
startIndex = (j + 1) % hole.num_vertices;
|
||||
}
|
||||
|
||||
if (isPointOnSegment(holeEnd.pt, p1, p2)) {
|
||||
endIndex = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isHoleVertices) {
|
||||
if (holeId >= 0 && startIndex >= 0 && endIndex >= 0) {
|
||||
Polygon hole = field.holes[holeId];
|
||||
int index = startIndex;
|
||||
int indexHoleIntersections = 1;
|
||||
boolean forward = true;
|
||||
|
||||
for (int step = 0; step < hole.num_vertices; step++) {
|
||||
if (indexHoleIntersections < layerHoleNum - 1) {
|
||||
Point current = hole.vertices[index];
|
||||
Point next = hole.vertices[(index + 1) % hole.num_vertices];
|
||||
Point intersectionPt = holeIntersections.get(l).get(indexHoleIntersections).pt;
|
||||
|
||||
if (forward && !isPointOnSegment(intersectionPt, current, next)) {
|
||||
forward = false;
|
||||
index = (index - 1 + hole.num_vertices) % hole.num_vertices;
|
||||
endIndex = (endIndex + 1) % hole.num_vertices;
|
||||
System.out.println("is_point_on_segment");
|
||||
}
|
||||
|
||||
if (indexHoleIntersections % 2 != 0) {
|
||||
pathPoints.add(hole.vertices[index]);
|
||||
}
|
||||
|
||||
pathPoints.add(holeIntersections.get(l).get(indexHoleIntersections).pt);
|
||||
indexHoleIntersections++;
|
||||
i++;
|
||||
} else {
|
||||
pathPoints.add(hole.vertices[index]);
|
||||
}
|
||||
|
||||
if (index == endIndex) break;
|
||||
|
||||
if (forward) {
|
||||
index = (index + 1) % hole.num_vertices;
|
||||
} else {
|
||||
index = (index - 1 + hole.num_vertices) % hole.num_vertices;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pathPoints.add(holeEnd.pt);
|
||||
i++;
|
||||
isHoleStart = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
pathPoints.add(intersections.get(i).pt);
|
||||
}
|
||||
} else {
|
||||
for (ProjectedPoint pp : intersections) {
|
||||
pathPoints.add(pp.pt);
|
||||
}
|
||||
}
|
||||
|
||||
direction *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
public static void latlonToXY(double lat0, double lon0, double lat, double lon, Point result) {
|
||||
double d_lat = Math.toRadians(lat - lat0);
|
||||
double d_lon = Math.toRadians(lon - lon0);
|
||||
double lat0_rad = Math.toRadians(lat0);
|
||||
|
||||
result.x = Earth_Radius * d_lon * Math.cos(lat0_rad);
|
||||
result.y = Earth_Radius * d_lat;
|
||||
}
|
||||
|
||||
public static void xyToLatlon(double lat0, double lon0, double x, double y, PathPoint result) {
|
||||
double lat0_rad = Math.toRadians(lat0);
|
||||
|
||||
result.lat = lat0 + (y / Earth_Radius) * (180.0 / M_PI);
|
||||
result.lon = lon0 + (x / (Earth_Radius * Math.cos(lat0_rad))) * (180.0 / M_PI);
|
||||
}
|
||||
|
||||
public static void getCoord(PathPoint[] gps, Point[] points, PathPoint start, int cnt) {
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
latlonToXY(start.lat, start.lon, gps[i].lat, gps[i].lon, points[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public static void getLatlon(PathPoint[] gps, Point[] points, PathPoint start, int cnt) {
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
xyToLatlon(start.lat, start.lon, points[i].x, points[i].y, gps[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void parseJson(String json) {
|
||||
RPPathData data = JsonUtils.parseObject(json,RPPathData.class);
|
||||
|
||||
PathPoint refPoint = data.refPoint;
|
||||
PathPoint[] outer = data.Polygon.outer.toArray(new PathPoint[0]);
|
||||
PathPoint start = data.scanLine.start;
|
||||
PathPoint end = data.scanLine.end;
|
||||
PathPoint[] holes = data.Polygon.holes.toArray(new PathPoint[0]);
|
||||
// 打印验证
|
||||
System.out.println("Ref Point: " + refPoint);
|
||||
System.out.println("Start: " + start);
|
||||
System.out.println("End: " + end);
|
||||
System.out.println("Outer:");
|
||||
for (PathPoint p : outer) {
|
||||
System.out.println(" " + p);
|
||||
}
|
||||
System.out.println("Holes:");
|
||||
for (PathPoint p : holes) {
|
||||
System.out.println(" " + p);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static List<LatAndLngEntity> generateMowingPath(String json) {
|
||||
RPPathData data = JsonUtils.parseObject(json,RPPathData.class);
|
||||
|
||||
PathPoint refPoint = data.refPoint;
|
||||
PathPoint[] outer = data.Polygon.outer.toArray(new PathPoint[0]);
|
||||
PathPoint start = data.scanLine.start;
|
||||
PathPoint end = data.scanLine.end;
|
||||
List<PathPoint> allHolePoints = new ArrayList<>();
|
||||
for (List<PathPoint> hole : data.Polygon.holes) {
|
||||
allHolePoints.addAll(hole);
|
||||
}
|
||||
PathPoint[] holes = allHolePoints.toArray(new PathPoint[0]);
|
||||
|
||||
|
||||
Point[] outerPoint = new Point[outer.length];
|
||||
Point startPoint = new Point(0, 0);
|
||||
Point endPoint = new Point(0, 0);
|
||||
Point[] holesPoint = new Point[holes.length];
|
||||
|
||||
latlonToXY(refPoint.lat, refPoint.lon, start.lat, start.lon, startPoint);
|
||||
latlonToXY(refPoint.lat, refPoint.lon, end.lat, end.lon, endPoint);
|
||||
|
||||
for (int i = 0; i < outer.length; i++) {
|
||||
outerPoint[i] = new Point(0, 0);
|
||||
latlonToXY(refPoint.lat, refPoint.lon, outer[i].lat, outer[i].lon, outerPoint[i]);
|
||||
System.out.printf("(%.14f, %.14f)\n", outerPoint[i].x, outerPoint[i].y);
|
||||
// Log.d("MowingPathGenerator", "Outer Point: " + "(" + outerPoint[i].x + ", " + outerPoint[i].y + " )");
|
||||
}
|
||||
|
||||
if (holes.length > 0) {
|
||||
for (int i = 0; i < holes.length; i++) {
|
||||
holesPoint[i] = new Point(0, 0);
|
||||
latlonToXY(refPoint.lat, refPoint.lon, holes[i].lat, holes[i].lon, holesPoint[i]);
|
||||
// Log.d("MowingPathGenerator", "holes Point: " + "(" + holesPoint[i].x + ", " + holesPoint[i].y + " )");
|
||||
System.out.printf("(%.14f, %.14f)\n", holesPoint[i].x, holesPoint[i].y);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Polygon outerPolygon = new Polygon(outerPoint, outer.length);
|
||||
|
||||
// Polygon holesPolygon[] = {new Polygon(holesPoint, holesPoint.length)};
|
||||
// PolygonWithHoles field = new PolygonWithHoles(outerPolygon, holesPolygon,holesPoint.length);
|
||||
|
||||
Polygon[] holesPolygons = new Polygon[data.Polygon.holes.size()];
|
||||
for (int i = 0; i < data.Polygon.holes.size(); i++) {
|
||||
List<PathPoint> hole = data.Polygon.holes.get(i);
|
||||
Point[] holePoints = new Point[hole.size()];
|
||||
for (int j = 0; j < hole.size(); j++) {
|
||||
holePoints[j] = new Point(0, 0);
|
||||
latlonToXY(refPoint.lat, refPoint.lon, hole.get(j).lat, hole.get(j).lon, holePoints[j]);
|
||||
}
|
||||
holesPolygons[i] = new Polygon(holePoints, holePoints.length);
|
||||
}
|
||||
PolygonWithHoles field = new PolygonWithHoles(outerPolygon, holesPolygons, holesPolygons.length);
|
||||
|
||||
|
||||
// PolygonWithHoles field = new PolygonWithHoles(outerPolygon, null,0);
|
||||
|
||||
double width = 0.8;
|
||||
List<Point> path = new ArrayList<>();
|
||||
|
||||
generateMowingPath(field, width, startPoint, endPoint, path);
|
||||
|
||||
PathPoint[] gpsout = new PathPoint[path.size()];
|
||||
|
||||
for (int i = 0; i < gpsout.length; i++) {
|
||||
gpsout[i] = new PathPoint(0, 0);
|
||||
}
|
||||
|
||||
for (int i = 0; i < path.size(); i++) {
|
||||
if (i >= gpsout.length) break;
|
||||
xyToLatlon(start.lat, start.lon, path.get(i).x, path.get(i).y, gpsout[i]);
|
||||
}
|
||||
List<LatAndLngEntity> Points = new ArrayList<>();
|
||||
|
||||
System.out.printf("Generated %d path points:\n", path.size());
|
||||
for (int i = 0; i < path.size(); i++) {
|
||||
if (i >= gpsout.length) break;
|
||||
System.out.printf("[%.14f, %.14f]\n", gpsout[i].lon, gpsout[i].lat);
|
||||
// Log.d("MowingPathGenerator", "gpsout Point: " + "(" + gpsout[i].lon + ", " + gpsout[i].lat + " )");
|
||||
LatAndLngEntity latAndLngEntity = new LatAndLngEntity();
|
||||
latAndLngEntity.setLat(gpsout[i].lat);
|
||||
latAndLngEntity.setLng(gpsout[i].lon);
|
||||
Points.add(latAndLngEntity);
|
||||
}
|
||||
|
||||
return Points;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// public static void main(String[] args) {
|
||||
//
|
||||
// PathPoint start = new PathPoint(32.08599985199932, 120.77586450935124);
|
||||
// PathPoint[] gpsout = new PathPoint[1024];
|
||||
// PathPoint[] gpsin = {
|
||||
// new PathPoint(32.08599985199932, 120.77586450935124),
|
||||
// new PathPoint(32.08624992154597, 120.77670803771835),
|
||||
// new PathPoint(32.08568874374706, 120.77710241458807),
|
||||
// new PathPoint(32.0854398968189, 120.77615838649545)
|
||||
// };
|
||||
//
|
||||
// PathPoint scanStart = new PathPoint(32.08599985199932, 120.77586450935124);
|
||||
// PathPoint scanEnd = new PathPoint(32.08624992154597, 120.77670803771835);
|
||||
// Point startPoint = new Point(0,0);
|
||||
// Point endPoint = new Point(0,0);
|
||||
//
|
||||
// latlonToXY(start.lat, start.lon, scanStart.lat, scanStart.lon, startPoint);
|
||||
// latlonToXY(start.lat, start.lon, scanEnd.lat, scanEnd.lon, endPoint);
|
||||
//
|
||||
// Point[] outerVertices = new Point[4];
|
||||
// for (int i = 0; i < 4; i++) {
|
||||
// outerVertices[i] = new Point(0, 0);
|
||||
// latlonToXY(start.lat, start.lon, gpsin[i].lat, gpsin[i].lon, outerVertices[i]);
|
||||
// System.out.printf("(%.14f, %.14f)\n", outerVertices[i].x, outerVertices[i].y);
|
||||
// }
|
||||
//
|
||||
// Polygon outer = new Polygon(outerVertices, 4);
|
||||
// Point[] hole1Vertices = {
|
||||
// new Point(40, -10), new Point(80, -10), new Point(80, -40),
|
||||
// new Point(60, -28), new Point(40, -40)
|
||||
// };
|
||||
// Polygon[] holes = {
|
||||
// new Polygon(hole1Vertices, 5)
|
||||
// };
|
||||
// PolygonWithHoles field = new PolygonWithHoles(outer, holes, 1);
|
||||
//
|
||||
// double width = 0.8;
|
||||
// List<Point> path = new ArrayList<>();
|
||||
//
|
||||
// generateMowingPath(field, width, startPoint, endPoint, path);
|
||||
//
|
||||
// for (int i = 0; i < gpsout.length; i++) {
|
||||
// gpsout[i] = new PathPoint(0, 0);
|
||||
// }
|
||||
//
|
||||
// for (int i = 0; i < path.size(); i++) {
|
||||
// if (i >= gpsout.length) break;
|
||||
// xyToLatlon(start.lat, start.lon, path.get(i).x, path.get(i).y, gpsout[i]);
|
||||
// }
|
||||
//
|
||||
// System.out.printf("Generated %d path points:\n", path.size());
|
||||
// for (int i = 0; i < path.size(); i++) {
|
||||
// if (i >= gpsout.length) break;
|
||||
// System.out.printf("{%.14f, %.14f}\n", gpsout[i].lon, gpsout[i].lat);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
@@ -1,20 +0,0 @@
|
||||
package com.maibu.entity.path;
|
||||
|
||||
import java.util.List;
|
||||
import com.maibu.entity.path.MowingPathGenerator.*;
|
||||
|
||||
public class RPPathData {
|
||||
public ScanLine scanLine;
|
||||
public PathPoint refPoint;
|
||||
public PolygonData Polygon;
|
||||
|
||||
public static class ScanLine {
|
||||
public PathPoint start;
|
||||
public PathPoint end;
|
||||
}
|
||||
|
||||
public static class PolygonData {
|
||||
public List<PathPoint> outer;
|
||||
public List<List<PathPoint>> holes;
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package com.maibu.entity.path;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class RoutePlanRecEntity {
|
||||
private byte header1;
|
||||
private byte header2;
|
||||
private byte commandType;
|
||||
private short pointNum;
|
||||
private byte status;
|
||||
private short crc16;
|
||||
private byte endFlag1;
|
||||
private byte endFlag2;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RoutePlanRecEntity{" +
|
||||
"header1=" + header1 +
|
||||
", header2=" + header2 +
|
||||
", commandType=" + commandType +
|
||||
", pointNum=" + pointNum +
|
||||
", status=" + status +
|
||||
", crc16=" + crc16 +
|
||||
", endFlag1=" + endFlag1 +
|
||||
", endFlag2=" + endFlag2 +
|
||||
'}';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
package com.maibu.entity.path;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
@Data
|
||||
public class RoutePlanSendEntity {
|
||||
|
||||
public RoutePlanSendEntity() {
|
||||
header1 = (byte) 0xAB;
|
||||
header2 = (byte) 0xAA;
|
||||
commandType = 0x01;
|
||||
pointCounts = 1;
|
||||
targetLatitude = 0;
|
||||
targetLongitude = 0;
|
||||
speed = 0x3E8;
|
||||
crc16 = 0;
|
||||
endFlag1 = (byte) 0xAA;
|
||||
endFlag2 = (byte) 0xAB;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RoutePlanSendEntity{" +
|
||||
"header1=" + header1 +
|
||||
", header2=" + header2 +
|
||||
", commandType=" + commandType +
|
||||
", pointCounts=" + pointCounts +
|
||||
", targetLatitude=" + targetLatitude +
|
||||
", targetLongitude=" + targetLongitude +
|
||||
", speed=" + speed +
|
||||
", crc16=" + crc16 +
|
||||
", endFlag1=" + endFlag1 +
|
||||
", endFlag2=" + endFlag2 +
|
||||
'}';
|
||||
}
|
||||
|
||||
public byte[] toBytes() {
|
||||
ByteBuffer buffer = ByteBuffer.allocate(27); // 修改为27字节
|
||||
buffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
buffer.put((byte) 0xAB);
|
||||
buffer.put((byte) 0xAA);
|
||||
|
||||
buffer.put((byte) 0x01);
|
||||
|
||||
buffer.putShort(pointCounts);
|
||||
|
||||
|
||||
long latitudeBits = Double.doubleToLongBits(targetLatitude);
|
||||
buffer.putLong(latitudeBits);
|
||||
|
||||
long longitudeBits = Double.doubleToLongBits(targetLongitude);
|
||||
buffer.putLong(longitudeBits);
|
||||
|
||||
buffer.putShort(speed);
|
||||
buffer.putShort(crc16);
|
||||
|
||||
buffer.put((byte) 0xAA);
|
||||
buffer.put((byte) 0xAB);
|
||||
|
||||
return buffer.array();
|
||||
}
|
||||
|
||||
private byte header1;
|
||||
private byte header2;
|
||||
private byte commandType;
|
||||
private short pointCounts;
|
||||
private double targetLatitude; // 改为 double
|
||||
private double targetLongitude; // 改为 double
|
||||
private short speed;
|
||||
private short crc16;
|
||||
private byte endFlag1;
|
||||
private byte endFlag2;
|
||||
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
package com.maibu.enums;
|
||||
|
||||
public enum CommandRequestType {
|
||||
switch_control
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
package com.maibu.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 比较操作符枚举类
|
||||
* 用于标准化管理比较类型,如>、<、between等
|
||||
* 基于项目现有的使用模式实现
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum CompareEnum {
|
||||
|
||||
/** 等于 */
|
||||
EQ("=", "等于", "=", true),
|
||||
|
||||
/** 不等于 */
|
||||
NEQ("!=", "不等于", "!=", true),
|
||||
|
||||
/** 大于 */
|
||||
GT(">", "大于", ">", true),
|
||||
|
||||
/** 小于 */
|
||||
LT("<", "小于", "<", true),
|
||||
|
||||
/** 大于等于 */
|
||||
GTE(">=", "大于等于", ">=", true),
|
||||
|
||||
/** 小于等于 */
|
||||
LTE("<=", "小于等于", "<=", true),
|
||||
|
||||
/** 在之间 */
|
||||
BETWEEN("between", "在之间", "between", false),
|
||||
|
||||
/** 不在之间 */
|
||||
NOT_BETWEEN("notBetween", "不在之间", "notBetween", false),
|
||||
|
||||
/** 包含 */
|
||||
CONTAIN("contain", "包含", "contain", true),
|
||||
|
||||
/** 不包含 */
|
||||
NOT_CONTAIN("notContain", "不包含", "notContain", true);
|
||||
|
||||
/** 操作符值(存储在数据库中) */
|
||||
private final String value;
|
||||
|
||||
/** 操作符名称(用于前端显示) */
|
||||
private final String name;
|
||||
|
||||
/** 表达式符号(用于计算表达式) */
|
||||
private final String symbol;
|
||||
|
||||
/** 是否为单值比较(true:单值, false:范围值) */
|
||||
private final boolean singleValue;
|
||||
|
||||
/**
|
||||
* 根据值获取比较操作符枚举
|
||||
* @param value 操作符值
|
||||
* @return 比较操作符枚举
|
||||
*/
|
||||
public static CompareEnum getByValue(String value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
for (CompareEnum operator : CompareEnum.values()) {
|
||||
if (operator.getValue().equals(value)) {
|
||||
return operator;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有比较操作符列表
|
||||
* @return 比较操作符列表
|
||||
*/
|
||||
public static List<CompareEnum> getAll() {
|
||||
return Arrays.asList(CompareEnum.values());
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否为范围比较操作符
|
||||
* @param value 操作符值
|
||||
* @return 是否为范围比较
|
||||
*/
|
||||
public static boolean isRangeOperator(String value) {
|
||||
CompareEnum operator = getByValue(value);
|
||||
return operator != null && !operator.isSingleValue();
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package com.maibu.enums;
|
||||
|
||||
public enum ConnectionCloseReason {
|
||||
NROMAL,
|
||||
TIMEOUT,
|
||||
REPEAT
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package com.maibu.enums;
|
||||
|
||||
public enum ConnectorStatus {
|
||||
ACTIVE, // 完全可用
|
||||
RECEIVER, // 禁言(不可发送但可以接收)
|
||||
DISABLED // 完全不可用
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package com.maibu.enums;
|
||||
|
||||
public enum ConnectorType {
|
||||
MASTER, // 上位机(主动绑定别人)
|
||||
SLAVE, // 下位机(只能被动绑定)
|
||||
GENERAL // 不区分角色(将来扩展用)
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package com.maibu.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum DeviceStatus {
|
||||
|
||||
|
||||
online(1, "online", "在线"),
|
||||
offline(0, "offline", "离线");
|
||||
|
||||
private int type;
|
||||
private String code;
|
||||
private String description;
|
||||
|
||||
public static DeviceStatus convert(int type) {
|
||||
for (DeviceStatus value : DeviceStatus.values()) {
|
||||
if (value.type == type) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static DeviceStatus convert(String code) {
|
||||
for (DeviceStatus value : DeviceStatus.values()) {
|
||||
if (value.code.equals(code)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package com.maibu.enums;
|
||||
|
||||
public enum RespondCode {
|
||||
/**
|
||||
* 账号已登录
|
||||
*/
|
||||
have_logged_in,
|
||||
|
||||
/**
|
||||
* 设备状态改变
|
||||
*/
|
||||
device_status_changed,
|
||||
/**
|
||||
* 设备错误推送
|
||||
*/
|
||||
device_error_push
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
package com.maibu.init;
|
||||
|
||||
import com.maibu.constant.FastBeeConstant;
|
||||
import com.maibu.domain.DevicePlan;
|
||||
import com.maibu.enums.DeviceTaskStaus;
|
||||
import com.maibu.core.business.DevicePlan;
|
||||
import com.maibu.core.enums.DeviceTaskStaus;
|
||||
import com.maibu.mapper.DevicePlanMapper;
|
||||
import com.maibu.mapper.SysUserClientMapper;
|
||||
import com.maibu.memory.GlobalMemory;
|
||||
import com.maibu.memory.SiteMemory;
|
||||
import com.maibu.mybatis.LambdaQueryWrapperX;
|
||||
import com.maibu.service.DevicePlanTaskMonitorService;
|
||||
import com.maibu.service.DeviceThreadService;
|
||||
@@ -92,7 +92,7 @@ public class InitThread implements ApplicationRunner {
|
||||
query.in(DevicePlan::getTaskStaus, list);
|
||||
List<DevicePlan> devicePlanList = devicePlanMapper.selectList(query);
|
||||
if(!CollectionUtils.isEmpty(devicePlanList)){
|
||||
devicePlanList.forEach(GlobalMemory::addDevicePlan);
|
||||
devicePlanList.forEach(SiteMemory::addDevicePlan);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,10 +2,10 @@ package com.maibu.manager;
|
||||
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.maibu.dto.Connector;
|
||||
import com.maibu.dto.NettyDevice;
|
||||
import com.maibu.enums.ConnectorStatus;
|
||||
import com.maibu.enums.ConnectorType;
|
||||
import com.maibu.core.enums.ConnectorStatus;
|
||||
import com.maibu.core.enums.ConnectorType;
|
||||
import com.maibu.core.business.device.Connector;
|
||||
import com.maibu.core.business.device.NettyDevice;
|
||||
import io.netty.channel.Channel;
|
||||
import lombok.Data;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.maibu.mapper;
|
||||
|
||||
import com.maibu.entity.ErrorIdentificationStandard;
|
||||
import com.maibu.core.business.ErrorIdentificationStandard;
|
||||
import com.maibu.mybatis.mapper.BaseMapperX;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
package com.maibu.memory;
|
||||
|
||||
import com.maibu.domain.DevicePlan;
|
||||
import com.maibu.domain.DevicePlanTask;
|
||||
import com.maibu.entity.ErrorIdentificationStandard;
|
||||
import lombok.Data;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@Component
|
||||
@Data
|
||||
public class GlobalMemory {
|
||||
|
||||
public List<ErrorIdentificationStandard> standard = null;
|
||||
|
||||
//key deviceId
|
||||
public static ConcurrentHashMap<String, List<DevicePlan>> devicePlanMap = new ConcurrentHashMap<>();
|
||||
//key deviceId prepare
|
||||
public static ConcurrentHashMap<String, List<DevicePlanTask>> devicePlanTaskPrepareMap = new ConcurrentHashMap<>();
|
||||
//key deviceId execute
|
||||
public static ConcurrentHashMap<String, DevicePlanTask> devicePlanTaskExecuteMap = new ConcurrentHashMap<>();
|
||||
|
||||
// 设备当前控制权在哪里key->deviceId value:userName:app/web/pc:token
|
||||
// public static final ConcurrentHashMap<String, String> controlLockMap = new ConcurrentHashMap<>();
|
||||
|
||||
|
||||
public static void addDevicePlan(DevicePlan devicePlan) {
|
||||
if (devicePlan != null && !StringUtils.isEmpty(devicePlan.getDeviceId())) {
|
||||
String deviceId = devicePlan.getDeviceId();
|
||||
List<DevicePlan> list = devicePlanMap.get(deviceId);
|
||||
if (CollectionUtils.isEmpty(list)) {
|
||||
list = new ArrayList<>();
|
||||
}
|
||||
boolean exists = list.stream()
|
||||
.anyMatch(l -> Objects.equals(l.getId(), devicePlan.getId()));
|
||||
if (!exists) {
|
||||
list.add(devicePlan);
|
||||
}
|
||||
devicePlanMap.put(deviceId, list);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void removeDevicePlan(DevicePlan devicePlan) {
|
||||
if (devicePlan != null && !StringUtils.isEmpty(devicePlan.getDeviceId())) {
|
||||
String deviceId = devicePlan.getDeviceId();
|
||||
List<DevicePlan> list = devicePlanMap.get(deviceId);
|
||||
if (!CollectionUtils.isEmpty(list)) {
|
||||
list.removeIf(x -> x.getId().equals(devicePlan.getId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void addDevicePlanPrepare(DevicePlanTask devicePlanTask) {
|
||||
if (devicePlanTask != null && !StringUtils.isEmpty(devicePlanTask.getDeviceId())) {
|
||||
String deviceId = devicePlanTask.getDeviceId();
|
||||
List<DevicePlanTask> list = devicePlanTaskPrepareMap.get(deviceId);
|
||||
if (CollectionUtils.isEmpty(list)) {
|
||||
list = new ArrayList<>();
|
||||
}
|
||||
list.add(devicePlanTask);
|
||||
devicePlanTaskPrepareMap.put(deviceId, list);
|
||||
}
|
||||
}
|
||||
|
||||
public static void removeDevicePlanPrepare(DevicePlanTask devicePlanTask) {
|
||||
if (devicePlanTask != null && !StringUtils.isEmpty(devicePlanTask.getDeviceId())) {
|
||||
String deviceId = devicePlanTask.getDeviceId();
|
||||
List<DevicePlanTask> list = devicePlanTaskPrepareMap.get(deviceId);
|
||||
if (!CollectionUtils.isEmpty(list)) {
|
||||
list.removeIf(x -> x.getId().equals(devicePlanTask.getId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static 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) {
|
||||
if (!StringUtils.isEmpty(deviceId)) {
|
||||
devicePlanTaskExecuteMap.remove(deviceId);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
package com.maibu.netty.handler;
|
||||
|
||||
import com.maibu.common.CommandConstant;
|
||||
import com.maibu.dto.Connector;
|
||||
import com.maibu.dto.NettyDevice;
|
||||
import com.maibu.enums.ConnectorType;
|
||||
import com.maibu.core.enums.ConnectorType;
|
||||
import com.maibu.core.business.device.Connector;
|
||||
import com.maibu.core.business.device.NettyDevice;
|
||||
import com.maibu.manager.DeviceSessionManager;
|
||||
import com.maibu.memory.GlobalMemory;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
@@ -35,6 +36,7 @@ public class CommandForwardHandler extends SimpleChannelInboundHandler<String> {
|
||||
Channel currentChannel = ctx.channel();
|
||||
byte[] bytes = Hex.decodeHex(msg.toCharArray());
|
||||
if (bytes.length > 3 && (bytes[2] == CommandConstant.remoteControl || bytes[2] == CommandConstant.path || bytes[2] == CommandConstant.status)) {
|
||||
|
||||
String senderDeviceId = deviceSessionManager.getDeviceIdByChannel(currentChannel);
|
||||
NettyDevice senderNettyDevice =
|
||||
senderDeviceId != null ? deviceSessionManager.getDevice(senderDeviceId) : null;
|
||||
|
||||
@@ -2,11 +2,11 @@ package com.maibu.netty.handler;
|
||||
|
||||
import com.maibu.common.CommandConstant;
|
||||
import com.maibu.common.NettyCacheKey;
|
||||
import com.maibu.core.business.DeviceRunStatistics;
|
||||
import com.maibu.core.business.DeviceRunningStatusHistory;
|
||||
import com.maibu.core.business.DeviceStatusRecordDTO;
|
||||
import com.maibu.core.redis.RedisCache;
|
||||
import com.maibu.domain.DeviceRunStatistics;
|
||||
import com.maibu.domain.DeviceRunningStatusHistory;
|
||||
import com.maibu.domain.DeviceStatusRecordDTO;
|
||||
import com.maibu.dto.NettyDevice;
|
||||
import com.maibu.core.business.device.NettyDevice;
|
||||
import com.maibu.manager.DeviceSessionManager;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
package com.maibu.netty.handler;
|
||||
|
||||
import com.maibu.common.CommandConstant;
|
||||
import com.maibu.common.Constant;
|
||||
import com.maibu.core.business.Device;
|
||||
import com.maibu.core.business.device.NettyDevice;
|
||||
import com.maibu.core.domain.entity.SysUser;
|
||||
import com.maibu.core.domain.entity.UserClient;
|
||||
import com.maibu.domain.Device;
|
||||
import com.maibu.core.enums.*;
|
||||
import com.maibu.core.enums.DeviceStatus;
|
||||
import com.maibu.dto.*;
|
||||
import com.maibu.enums.*;
|
||||
import com.maibu.manager.DeviceSessionManager;
|
||||
import com.maibu.mapper.DeviceRunStatisticsMapper;
|
||||
import com.maibu.service.IDeviceService;
|
||||
@@ -32,9 +35,7 @@ import org.springframework.util.CollectionUtils;
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@Component
|
||||
@@ -43,9 +44,6 @@ public class DeviceConnectHandler extends SimpleChannelInboundHandler<String> {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(DeviceConnectHandler.class);
|
||||
|
||||
public static final AttributeKey<String> ATT_DEVICE_ID = AttributeKey.valueOf("deviceId");
|
||||
public static final AttributeKey<ConnectionCloseReason> ATT_CLOSE_REASON = AttributeKey.valueOf("closeReason");
|
||||
|
||||
//记录切换控制权请求来源 key 是请求的masterId,value是控制当前设备的主机
|
||||
private final ConcurrentHashMap<String, String> controlRequestMap = new ConcurrentHashMap<>();
|
||||
|
||||
@@ -80,8 +78,8 @@ public class DeviceConnectHandler extends SimpleChannelInboundHandler<String> {
|
||||
@Override
|
||||
public void channelInactive(ChannelHandlerContext ctx) {
|
||||
Channel channel = ctx.channel();
|
||||
ConnectionCloseReason reason = channel.attr(ATT_CLOSE_REASON).get();
|
||||
String deviceId = channel.attr(ATT_DEVICE_ID).get();
|
||||
ConnectionCloseReason reason = channel.attr(Constant.ATT_CLOSE_REASON).get();
|
||||
String deviceId = channel.attr(Constant.ATT_DEVICE_ID).get();
|
||||
|
||||
if (reason == ConnectionCloseReason.REPEAT) {
|
||||
logger.warn("重复连接断开: {}", channel.remoteAddress());
|
||||
@@ -120,7 +118,7 @@ public class DeviceConnectHandler extends SimpleChannelInboundHandler<String> {
|
||||
Device device = deviceService.selectDeviceBySerialNumber(deviceId);
|
||||
if (device != null) {
|
||||
device.setOnlineStatus(DeviceStatus.offline.getType());
|
||||
device.setUpdateTime(new Date());
|
||||
device.setUpdateTime(LocalDateTime.now());
|
||||
deviceService.updateDeviceBySelf(device);
|
||||
//todo 更新历史作业消息
|
||||
}
|
||||
@@ -253,13 +251,13 @@ public class DeviceConnectHandler extends SimpleChannelInboundHandler<String> {
|
||||
device.setTenantId(-1L);
|
||||
device.setFirmwareVersion(BigDecimal.valueOf(1.0));
|
||||
device.setProductName("割草机产品MC700");
|
||||
device.setCreateTime(new Date());
|
||||
device.setUpdateTime(new Date());
|
||||
device.setCreateTime(LocalDateTime.now());
|
||||
device.setUpdateTime(LocalDateTime.now());
|
||||
deviceService.insertDeviceBySelf(device);
|
||||
} else {
|
||||
device.setStatus(3);
|
||||
device.setOnlineStatus(DeviceStatus.online.getType());
|
||||
device.setUpdateTime(new Date());
|
||||
device.setUpdateTime(LocalDateTime.now());
|
||||
deviceService.updateDeviceBySelf(device);
|
||||
}
|
||||
NettyDevice slaveDevice = sessionManager.getDevice(data);
|
||||
@@ -444,12 +442,12 @@ public class DeviceConnectHandler extends SimpleChannelInboundHandler<String> {
|
||||
}
|
||||
|
||||
private void handleSlaveConnect(ChannelHandlerContext ctx, String slaveId) {
|
||||
ctx.channel().attr(ATT_DEVICE_ID).set(slaveId);
|
||||
ctx.channel().attr(Constant.ATT_DEVICE_ID).set(slaveId);
|
||||
sessionManager.registerDevice(slaveId, ctx.channel(), ConnectorType.SLAVE, ConnectorStatus.ACTIVE, null);
|
||||
}
|
||||
|
||||
private void handleMasterConnect(ChannelHandlerContext ctx, String masterId, String slaveId, ConnectorStatus status) {
|
||||
ctx.channel().attr(ATT_DEVICE_ID).set(masterId);
|
||||
ctx.channel().attr(Constant.ATT_DEVICE_ID).set(masterId);
|
||||
sessionManager.registerDevice(masterId, ctx.channel(), ConnectorType.MASTER, status, slaveId);
|
||||
// sessionManager.bindConnector(masterId, slaveId);
|
||||
}
|
||||
@@ -457,7 +455,7 @@ public class DeviceConnectHandler extends SimpleChannelInboundHandler<String> {
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
|
||||
String deviceId = ctx.channel().attr(ATT_DEVICE_ID).get();
|
||||
String deviceId = ctx.channel().attr(Constant.ATT_DEVICE_ID).get();
|
||||
logger.error("异常设备 {} 出现错误: {}", deviceId, cause.getMessage(), cause);
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package com.maibu.scheduled;
|
||||
|
||||
import com.maibu.common.NettyCacheKey;
|
||||
import com.maibu.core.business.DevicePlan;
|
||||
import com.maibu.core.business.DeviceStatusRecordDTO;
|
||||
import com.maibu.core.redis.RedisCache;
|
||||
import com.maibu.domain.DevicePlan;
|
||||
import com.maibu.domain.DeviceStatusRecordDTO;
|
||||
import com.maibu.mapper.DeviceStatusHistoryMapper;
|
||||
import com.maibu.memory.GlobalMemory;
|
||||
import com.maibu.memory.SiteMemory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -57,7 +57,7 @@ public class ScheduledTask {
|
||||
@Scheduled(cron = "0 0 0 * * ?")
|
||||
public void refreshDevicePlanTask() {
|
||||
System.out.println("0点定时刷新状态");
|
||||
Map<String, List<DevicePlan>> map = GlobalMemory.devicePlanMap;
|
||||
Map<String, List<DevicePlan>> map = SiteMemory.devicePlanMap;
|
||||
if (!CollectionUtils.isEmpty(map.keySet())) {
|
||||
map.values().forEach(x -> {
|
||||
if (!CollectionUtils.isEmpty(x)) {
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
package com.maibu.service;
|
||||
|
||||
|
||||
import com.maibu.domain.DevicePlan;
|
||||
import com.maibu.domain.DevicePlanTask;
|
||||
import com.maibu.domain.DeviceTaskPlanRule;
|
||||
import com.maibu.dto.NettyDevice;
|
||||
import com.maibu.enums.DeviceTaskPlanRepeatType;
|
||||
import com.maibu.enums.DeviceTaskStaus;
|
||||
import com.maibu.core.business.DevicePlan;
|
||||
import com.maibu.core.business.DevicePlanTask;
|
||||
import com.maibu.core.business.DeviceTaskPlanRule;
|
||||
import com.maibu.core.business.WorkRecord;
|
||||
import com.maibu.core.enums.DeviceTaskPlanRepeatType;
|
||||
import com.maibu.core.enums.DeviceTaskStaus;
|
||||
import com.maibu.core.business.device.NettyDevice;
|
||||
import com.maibu.manager.DeviceSessionManager;
|
||||
import com.maibu.mapper.DevicePlanMapper;
|
||||
import com.maibu.mapper.DevicePlanTaskMapper;
|
||||
import com.maibu.mapper.WorkRecordMapper;
|
||||
import com.maibu.memory.GlobalMemory;
|
||||
import com.maibu.model.WorkRecord;
|
||||
import com.maibu.memory.SiteMemory;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -34,7 +34,7 @@ public class DevicePlanTaskMonitorService {
|
||||
|
||||
|
||||
@Autowired
|
||||
private GlobalMemory globalMemory;
|
||||
private SiteMemory siteMemory;
|
||||
|
||||
@Autowired
|
||||
private DevicePlanTaskMapper devicePlanTaskMapper;
|
||||
@@ -57,7 +57,7 @@ public class DevicePlanTaskMonitorService {
|
||||
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
|
||||
executor.scheduleWithFixedDelay(() -> {
|
||||
try {
|
||||
Map<String, List<DevicePlan>> planMap = GlobalMemory.devicePlanMap;
|
||||
Map<String, List<DevicePlan>> planMap = SiteMemory.devicePlanMap;
|
||||
if (!CollectionUtils.isEmpty(planMap.values())) {
|
||||
Iterator<String> iterator = planMap.keySet().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
@@ -109,7 +109,7 @@ public class DevicePlanTaskMonitorService {
|
||||
devicePlanTask.setCreateTime(LocalDateTime.now());
|
||||
devicePlanTask.setTaskType("");//待拓展任务类型
|
||||
devicePlanTaskMapper.insert(devicePlanTask);
|
||||
globalMemory.addDevicePlanPrepare(devicePlanTask);
|
||||
siteMemory.addDevicePlanPrepare(devicePlanTask);
|
||||
//啥时候重置?每日0点?
|
||||
devicePlan.setDayTriggerFlag(true);
|
||||
devicePlan.setUpdateTime(LocalDateTime.now());
|
||||
@@ -120,7 +120,7 @@ public class DevicePlanTaskMonitorService {
|
||||
if (endTime != null && endTime.isEqual(today)) {
|
||||
devicePlan.setFinishTime(LocalDateTime.now());
|
||||
devicePlan.setTaskStaus(DeviceTaskStaus.FINISH);
|
||||
GlobalMemory.removeDevicePlan(devicePlan);
|
||||
SiteMemory.removeDevicePlan(devicePlan);
|
||||
}
|
||||
devicePlanMapper.updateById(devicePlan);
|
||||
}
|
||||
@@ -143,7 +143,7 @@ public class DevicePlanTaskMonitorService {
|
||||
devicePlanTask.setCreateTime(LocalDateTime.now());
|
||||
devicePlanTask.setTaskType("");//待拓展任务类型
|
||||
devicePlanTaskMapper.insert(devicePlanTask);
|
||||
globalMemory.addDevicePlanPrepare(devicePlanTask);
|
||||
siteMemory.addDevicePlanPrepare(devicePlanTask);
|
||||
//啥时候重置?每日0点?
|
||||
devicePlan.setDayTriggerFlag(true);
|
||||
devicePlan.setUpdateTime(LocalDateTime.now());
|
||||
@@ -153,7 +153,7 @@ public class DevicePlanTaskMonitorService {
|
||||
if (endTime != null && endTime.isEqual(today)) {
|
||||
devicePlan.setFinishTime(LocalDateTime.now());
|
||||
devicePlan.setTaskStaus(DeviceTaskStaus.FINISH);
|
||||
GlobalMemory.removeDevicePlan(devicePlan);
|
||||
SiteMemory.removeDevicePlan(devicePlan);
|
||||
}
|
||||
devicePlanMapper.updateById(devicePlan);
|
||||
}
|
||||
@@ -175,7 +175,7 @@ public class DevicePlanTaskMonitorService {
|
||||
devicePlanTask.setCreateTime(LocalDateTime.now());
|
||||
devicePlanTask.setTaskType("");//待拓展任务类型
|
||||
devicePlanTaskMapper.insert(devicePlanTask);
|
||||
globalMemory.addDevicePlanPrepare(devicePlanTask);
|
||||
siteMemory.addDevicePlanPrepare(devicePlanTask);
|
||||
//啥时候重置?每日0点?
|
||||
devicePlan.setDayTriggerFlag(true);
|
||||
devicePlan.setUpdateTime(LocalDateTime.now());
|
||||
@@ -185,7 +185,7 @@ public class DevicePlanTaskMonitorService {
|
||||
if (endTime != null && endTime.isEqual(today)) {
|
||||
devicePlan.setFinishTime(LocalDateTime.now());
|
||||
devicePlan.setTaskStaus(DeviceTaskStaus.FINISH);
|
||||
GlobalMemory.removeDevicePlan(devicePlan);
|
||||
SiteMemory.removeDevicePlan(devicePlan);
|
||||
}
|
||||
devicePlanMapper.updateById(devicePlan);
|
||||
}
|
||||
@@ -202,7 +202,7 @@ public class DevicePlanTaskMonitorService {
|
||||
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
|
||||
executor.scheduleWithFixedDelay(() -> {
|
||||
try {
|
||||
Map<String, List<DevicePlanTask>> planMap = GlobalMemory.devicePlanTaskPrepareMap;
|
||||
Map<String, List<DevicePlanTask>> planMap = SiteMemory.devicePlanTaskPrepareMap;
|
||||
if (!CollectionUtils.isEmpty(planMap.keySet())) {
|
||||
planMap.keySet().forEach(key -> {
|
||||
NettyDevice device = deviceSessionManager.getDevice(key);
|
||||
@@ -221,9 +221,9 @@ public class DevicePlanTaskMonitorService {
|
||||
DevicePlanTask devicePlanTask = list.get(0);
|
||||
String deviceId = devicePlanTask.getDeviceId();
|
||||
if (!StringUtils.isEmpty(deviceId) && deviceId.equals(key)) {
|
||||
GlobalMemory.addDevicePlanExecute(devicePlanTask);
|
||||
SiteMemory.addDevicePlanExecute(devicePlanTask);
|
||||
device.setCurrentTaskId(devicePlanTask.getId());
|
||||
GlobalMemory.removeDevicePlanPrepare(devicePlanTask);
|
||||
SiteMemory.removeDevicePlanPrepare(devicePlanTask);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -241,7 +241,7 @@ public class DevicePlanTaskMonitorService {
|
||||
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
|
||||
executor.scheduleWithFixedDelay(() -> {
|
||||
try {
|
||||
Map<String, DevicePlanTask> planMap = GlobalMemory.devicePlanTaskExecuteMap;
|
||||
Map<String, DevicePlanTask> planMap = SiteMemory.devicePlanTaskExecuteMap;
|
||||
if (!CollectionUtils.isEmpty(planMap.keySet())) {
|
||||
planMap.keySet().forEach(key -> {
|
||||
NettyDevice device = deviceSessionManager.getDevice(key);
|
||||
|
||||
@@ -1,22 +1,18 @@
|
||||
package com.maibu.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.maibu.core.business.*;
|
||||
import com.maibu.core.domain.model.LoginUser;
|
||||
import com.maibu.domain.Device;
|
||||
import com.maibu.domain.DevicePlan;
|
||||
import com.maibu.domain.DevicePlanTask;
|
||||
import com.maibu.domain.DeviceTaskPlanRule;
|
||||
import com.maibu.core.enums.DeviceTaskStaus;
|
||||
import com.maibu.dto.DevicePlanStatisticsDTO;
|
||||
import com.maibu.dto.DevicePlanTaskStatisticsDTO;
|
||||
import com.maibu.dto.DeviceTaskQueryDTO;
|
||||
import com.maibu.dto.DeviceWorkStatisticsDTO;
|
||||
import com.maibu.enums.DeviceTaskStaus;
|
||||
import com.maibu.mapper.DeviceMapper;
|
||||
import com.maibu.mapper.DevicePlanMapper;
|
||||
import com.maibu.mapper.DevicePlanTaskMapper;
|
||||
import com.maibu.mapper.WorkRecordMapper;
|
||||
import com.maibu.memory.GlobalMemory;
|
||||
import com.maibu.model.WorkRecord;
|
||||
import com.maibu.memory.SiteMemory;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -55,7 +51,7 @@ public class DeviceTaskService {
|
||||
devicePlan.setUpdateTime(LocalDateTime.now());
|
||||
transferDays(devicePlan);
|
||||
int i = devicePlanMapper.updateById(devicePlan);
|
||||
GlobalMemory.addDevicePlan(devicePlan);
|
||||
SiteMemory.addDevicePlan(devicePlan);
|
||||
return i;
|
||||
} else {
|
||||
devicePlan.setTaskStaus(DeviceTaskStaus.NEW);
|
||||
@@ -63,7 +59,7 @@ public class DeviceTaskService {
|
||||
devicePlan.setCreateBy(loginUser.getUsername());
|
||||
transferDays(devicePlan);
|
||||
int i = devicePlanMapper.insert(devicePlan);
|
||||
GlobalMemory.addDevicePlan(devicePlan);
|
||||
SiteMemory.addDevicePlan(devicePlan);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@@ -148,7 +144,7 @@ public class DeviceTaskService {
|
||||
DevicePlan planTask = devicePlanMapper.selectById(id);
|
||||
if (planTask != null) {
|
||||
planTask.setDelFlag(1);
|
||||
GlobalMemory.removeDevicePlan(planTask);
|
||||
SiteMemory.removeDevicePlan(planTask);
|
||||
return devicePlanMapper.updateById(planTask);
|
||||
}
|
||||
return 0;
|
||||
@@ -308,8 +304,8 @@ public class DeviceTaskService {
|
||||
|
||||
public List<DevicePlanTask> deviceTaskPool(DeviceTaskQueryDTO dto) {
|
||||
List<DevicePlanTask> list = new ArrayList<>();
|
||||
GlobalMemory.devicePlanTaskPrepareMap.values().forEach(list::addAll);
|
||||
list.addAll(GlobalMemory.devicePlanTaskExecuteMap.values());
|
||||
SiteMemory.devicePlanTaskPrepareMap.values().forEach(list::addAll);
|
||||
list.addAll(SiteMemory.devicePlanTaskExecuteMap.values());
|
||||
if (dto != null) {
|
||||
if (dto.getTaskStaus() != null) {
|
||||
list = list.stream().filter(x -> x.getTaskStaus().equals(dto.getTaskStaus())).collect(Collectors.toList());
|
||||
|
||||
@@ -5,18 +5,18 @@ import cn.hutool.core.io.IoUtil;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.maibu.common.CommandConstant;
|
||||
import com.maibu.common.NettyCacheKey;
|
||||
import com.maibu.core.business.DeviceRunningStatusHistory;
|
||||
import com.maibu.core.business.DeviceStatusRecordDTO;
|
||||
import com.maibu.core.enums.CompareEnum;
|
||||
import com.maibu.core.enums.RespondCode;
|
||||
import com.maibu.core.redis.RedisCache;
|
||||
import com.maibu.domain.DeviceRunningStatusHistory;
|
||||
import com.maibu.domain.DeviceStatusRecordDTO;
|
||||
import com.maibu.dto.DeviceErrorPushDTO;
|
||||
import com.maibu.dto.DeviceErrorPushDetail;
|
||||
import com.maibu.dto.NettyDevice;
|
||||
import com.maibu.entity.ErrorIdentificationStandard;
|
||||
import com.maibu.enums.CompareEnum;
|
||||
import com.maibu.enums.RespondCode;
|
||||
import com.maibu.core.business.device.NettyDevice;
|
||||
import com.maibu.core.business.ErrorIdentificationStandard;
|
||||
import com.maibu.manager.DeviceSessionManager;
|
||||
import com.maibu.mapper.ErrorIdentificationStandardMapper;
|
||||
import com.maibu.memory.GlobalMemory;
|
||||
import com.maibu.memory.SiteMemory;
|
||||
import com.maibu.utils.CommandUtils;
|
||||
import com.maibu.utils.CompareUtils;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
@@ -47,7 +47,7 @@ public class DeviceThreadService {
|
||||
private ResourceLoader resourceLoader;
|
||||
|
||||
@Autowired
|
||||
private GlobalMemory globalMemory;
|
||||
private SiteMemory siteMemory;
|
||||
|
||||
@Autowired
|
||||
private RedisCache redisCache;
|
||||
@@ -73,7 +73,7 @@ public class DeviceThreadService {
|
||||
if (recordDTO != null && !CollectionUtils.isEmpty(recordDTO.getHistories())) {
|
||||
recordDTO.getHistories().sort(Comparator.comparing(DeviceRunningStatusHistory::getCreateTime).reversed());
|
||||
DeviceRunningStatusHistory history = recordDTO.getHistories().get(0);
|
||||
List<DeviceErrorPushDetail> compared = compareErrorStandard(history, globalMemory.standard);
|
||||
List<DeviceErrorPushDetail> compared = compareErrorStandard(history, siteMemory.standard);
|
||||
|
||||
String[] parts = k.split(":");
|
||||
String deviceId = parts[1];
|
||||
@@ -95,16 +95,16 @@ public class DeviceThreadService {
|
||||
}
|
||||
|
||||
public void initStandard() throws IOException {
|
||||
if (globalMemory.standard == null) {
|
||||
if (siteMemory.standard == null) {
|
||||
List<ErrorIdentificationStandard> standards = standardMapper.selectList();
|
||||
if (CollectionUtils.isEmpty(standards)) {
|
||||
// 读取resource目录下的device-config.json文件
|
||||
Resource resource = resourceLoader.getResource("classpath:errorStandard.json");
|
||||
// 使用fastjson2转换为DeviceConfig对象
|
||||
String jsonContent = IoUtil.readUtf8(resource.getInputStream());
|
||||
globalMemory.standard = JSON.parseArray(jsonContent, ErrorIdentificationStandard.class);
|
||||
siteMemory.standard = JSON.parseArray(jsonContent, ErrorIdentificationStandard.class);
|
||||
} else {
|
||||
globalMemory.standard = standards;
|
||||
siteMemory.standard = standards;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.maibu.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.maibu.domain.DeviceRunningStatusHistory;
|
||||
import com.maibu.entity.ErrorIdentificationStandard;
|
||||
import com.maibu.core.business.DeviceRunningStatusHistory;
|
||||
import com.maibu.core.business.ErrorIdentificationStandard;
|
||||
import com.maibu.mapper.DeviceStatusHistoryMapper;
|
||||
import com.maibu.mapper.ErrorIdentificationStandardMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
package com.maibu.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.maibu.core.business.Device;
|
||||
import com.maibu.core.business.device.NettyDevice;
|
||||
import com.maibu.core.domain.AjaxResult;
|
||||
import com.maibu.core.domain.entity.UserClient;
|
||||
import com.maibu.core.domain.model.LoginUser;
|
||||
import com.maibu.domain.Device;
|
||||
import com.maibu.dto.*;
|
||||
import com.maibu.enums.ConnectorStatus;
|
||||
import com.maibu.core.enums.ConnectorStatus;
|
||||
import com.maibu.manager.DeviceSessionManager;
|
||||
import com.maibu.mapper.DeviceMapper;
|
||||
import com.maibu.mapper.SysUserClientMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import com.maibu.dto.*;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@@ -57,7 +58,7 @@ public class TransferDeviceService {
|
||||
}
|
||||
device.setTenantId(user.getUserId());
|
||||
device.setTenantName(user.getUsername());
|
||||
device.setUpdateTime(new Date());
|
||||
device.setUpdateTime(LocalDateTime.now());
|
||||
device.setDeviceAlias(deviceAlias);
|
||||
device.setActiveTime(new Date());
|
||||
iDeviceService.updateDeviceBySelf(device);
|
||||
@@ -87,7 +88,7 @@ public class TransferDeviceService {
|
||||
}
|
||||
device.setTenantId(-1L);
|
||||
device.setTenantName("");
|
||||
device.setUpdateTime(new Date());
|
||||
device.setUpdateTime(LocalDateTime.now());
|
||||
device.setDeviceAlias("");
|
||||
// deviceMapper.updateById(device);
|
||||
iDeviceService.updateDeviceBySelf(device);
|
||||
@@ -109,7 +110,7 @@ public class TransferDeviceService {
|
||||
//删除从的连接关系
|
||||
NettyDevice oldSlaveDevice = sessionManager.getDevice(oldSlave);
|
||||
if (oldSlaveDevice != null && !CollectionUtils.isEmpty(oldSlaveDevice.getConnectedConnectors())) {
|
||||
Set<Connector> connectedDevices = oldSlaveDevice.getConnectedConnectors();
|
||||
Set<com.maibu.core.business.device.Connector> connectedDevices = oldSlaveDevice.getConnectedConnectors();
|
||||
connectedDevices.removeIf(x -> x.getConnectorId().equals(masterId));
|
||||
}
|
||||
}
|
||||
@@ -143,7 +144,7 @@ public class TransferDeviceService {
|
||||
return AjaxResult.error("无操作权限");
|
||||
}
|
||||
device.setDeviceAlias(bindDTO.getDeviceAlias());
|
||||
device.setUpdateTime(new Date());
|
||||
device.setUpdateTime(LocalDateTime.now());
|
||||
device.setCreateBy(user.getUsername());
|
||||
iDeviceService.updateDeviceBySelf(device);
|
||||
return AjaxResult.success(true);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.maibu.utils;
|
||||
|
||||
import com.maibu.enums.CompareEnum;
|
||||
import com.maibu.core.enums.CompareEnum;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user