update
This commit is contained in:
@@ -5,6 +5,8 @@ import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.maibu.annotation.Excel;
|
||||
import com.maibu.core.domain.BaseDO;
|
||||
import com.maibu.influxdb.MowerRealTimeData;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
@@ -220,9 +222,8 @@ public class Device extends BaseDO {
|
||||
@TableField(exist = false)
|
||||
private DeviceRunningStatusHistory lastRunningStatus;
|
||||
|
||||
public DeviceRunningStatusHistory getLastRunningStatus() {
|
||||
return lastRunningStatus != null ? lastRunningStatus : new DeviceRunningStatusHistory();
|
||||
}
|
||||
@TableField(exist = false)
|
||||
private MowerRealTimeData lastMowerRealTimeData;
|
||||
|
||||
@TableField(exist = false)
|
||||
private Map<Integer,Integer> statusStatistics;
|
||||
|
||||
@@ -6,11 +6,10 @@ 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
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName(value = "iot_work_record", autoResultMap = true)
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.maibu.core.business.device;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class DeviceStatusDetail {
|
||||
private String name;
|
||||
private String value;
|
||||
private String unit;
|
||||
}
|
||||
@@ -98,6 +98,8 @@ public class NettyDevice extends Connector {
|
||||
siteMemory.removeDevicePlanExecute(task.getDeviceId());
|
||||
task = null;
|
||||
currentTaskId = null;
|
||||
currentPoint = null;
|
||||
locationQueue.clear();
|
||||
executingTask = false;
|
||||
return finishId;
|
||||
}
|
||||
@@ -113,6 +115,7 @@ public class NettyDevice extends Connector {
|
||||
siteMemory.removeDevicePlanExecute(task.getDeviceId());
|
||||
task = null;
|
||||
currentTaskId = null;
|
||||
currentPoint = null;
|
||||
locationQueue.clear();
|
||||
executingTask = false;
|
||||
}
|
||||
@@ -152,8 +155,9 @@ public class NettyDevice extends Connector {
|
||||
task.setTaskStaus(DeviceTaskStaus.EXECUTING);
|
||||
executingTask = true;
|
||||
sendPathCommand((byte) 0x01, (short) 3, 0.00d, 0.00d, (short) 0);
|
||||
Thread.sleep(1000);
|
||||
sendPathCommand((byte) 0x01, (short) 1, currentPoint.getLat(), currentPoint.getLng(), (short) 0);
|
||||
// Thread.sleep(1000);
|
||||
// sendPathCommand((byte) 0x01, (short) 1, currentPoint.getLat(),
|
||||
// currentPoint.getLng(), (short) 0);
|
||||
// sendNextPoint();
|
||||
return true;
|
||||
} else {
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
package com.maibu.influxdb;
|
||||
|
||||
|
||||
import com.maibu.influxdb.inter.InfluxField;
|
||||
import com.maibu.influxdb.inter.InfluxTag;
|
||||
import com.maibu.influxdb.inter.InfluxTime;
|
||||
import com.maibu.influxdb.inter.InfluxMeasurement;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
//@Measurement(name = "device_data")
|
||||
@Data
|
||||
@InfluxMeasurement("device_data")
|
||||
public class DeviceData {
|
||||
|
||||
// @Column(tag = true)
|
||||
@InfluxTag
|
||||
private String deviceId;
|
||||
|
||||
@InfluxField
|
||||
private Double temperature;
|
||||
|
||||
@InfluxField
|
||||
private Double voltage;
|
||||
|
||||
@InfluxTime
|
||||
private Instant time;
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
package com.maibu.influxdb;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import com.influxdb.query.FluxRecord;
|
||||
import com.maibu.influxdb.inter.InfluxField;
|
||||
import com.maibu.influxdb.inter.InfluxMeasurement;
|
||||
import com.maibu.influxdb.inter.InfluxTag;
|
||||
import com.maibu.influxdb.inter.InfluxTime;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
//@Measurement(name = "device_data")
|
||||
@Data
|
||||
@InfluxMeasurement("mower_realTime_data")
|
||||
public class MowerRealTimeData {
|
||||
|
||||
// @Column(tag = true)
|
||||
@InfluxTag
|
||||
private String deviceId;
|
||||
|
||||
@InfluxField
|
||||
private String voltage;// 电压
|
||||
|
||||
@InfluxField
|
||||
private String leftTargetSpeed; // 左轮目标速度
|
||||
|
||||
@InfluxField
|
||||
private String rightTargetSpeed;// 右轮目标速度
|
||||
|
||||
@InfluxField
|
||||
private String leftMeasureSpeed;// 左轮测量速度
|
||||
|
||||
@InfluxField
|
||||
private String rightMeasureSpeed;// 右轮测量速度
|
||||
|
||||
@InfluxField
|
||||
private String leftCurrent;// 左轮电流
|
||||
|
||||
@InfluxField
|
||||
private String rightCurrent;// 右轮电流
|
||||
|
||||
@InfluxField
|
||||
private String leftMotorTemp;// 左轮温度
|
||||
|
||||
@InfluxField
|
||||
private String rightMotorTemp;// 右轮温度
|
||||
|
||||
@InfluxField
|
||||
private String chipTemp;// 芯片温度
|
||||
|
||||
@InfluxField
|
||||
private String yaw;// 偏航角
|
||||
|
||||
@InfluxField
|
||||
private String pitch;// 仰俯角
|
||||
|
||||
@InfluxField
|
||||
private String roll;// 翻滚角
|
||||
|
||||
@InfluxField
|
||||
private String satelliteCnt;// 跟踪的卫星数
|
||||
|
||||
@InfluxField
|
||||
private String qual;// 定位质量
|
||||
|
||||
@InfluxField
|
||||
private String headingStatus;// 航向角状态
|
||||
|
||||
@InfluxField
|
||||
private String latitude;// 纬度
|
||||
|
||||
@InfluxField
|
||||
private String longitude;// 经度
|
||||
|
||||
@InfluxField
|
||||
private String cuttingSpeed;// 割刀速度
|
||||
|
||||
@InfluxField
|
||||
private String controlMode;// 控制模式
|
||||
|
||||
@InfluxField
|
||||
private String battery;// 电池电量
|
||||
|
||||
@InfluxField
|
||||
private String workingArea;// 作业面积
|
||||
|
||||
@InfluxField
|
||||
private String obstacleSign;// 障碍物标志位
|
||||
|
||||
@InfluxTime
|
||||
private Instant time;
|
||||
|
||||
public static MowerRealTimeData transferLatestInfluxData(FluxRecord record) {
|
||||
|
||||
if (record == null || record.getValue() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
MowerRealTimeData data = new MowerRealTimeData();
|
||||
|
||||
data.setDeviceId((String) record.getValueByKey("deviceId"));
|
||||
|
||||
data.setVoltage((String) record.getValueByKey("voltage"));
|
||||
|
||||
data.setLeftTargetSpeed((String) record.getValueByKey("leftTargetSpeed"));
|
||||
|
||||
data.setRightTargetSpeed((String) record.getValueByKey("rightTargetSpeed"));
|
||||
|
||||
data.setLeftMeasureSpeed((String) record.getValueByKey("leftMeasureSpeed"));
|
||||
|
||||
data.setRightMeasureSpeed((String) record.getValueByKey("rightMeasureSpeed"));
|
||||
|
||||
data.setLeftMotorTemp((String) record.getValueByKey("leftMotorTemp"));
|
||||
|
||||
data.setRightMotorTemp((String) record.getValueByKey("rightMotorTemp"));
|
||||
|
||||
data.setLeftCurrent((String) record.getValueByKey("leftCurrent"));
|
||||
|
||||
data.setRightCurrent((String) record.getValueByKey("rightCurrent"));
|
||||
|
||||
data.setChipTemp((String) record.getValueByKey("chipTemp"));
|
||||
|
||||
data.setYaw((String) record.getValueByKey("yaw"));
|
||||
|
||||
data.setPitch((String) record.getValueByKey("pitch"));
|
||||
|
||||
data.setRoll((String) record.getValueByKey("roll"));
|
||||
|
||||
data.setSatelliteCnt((String) record.getValueByKey("satelliteCnt"));
|
||||
|
||||
data.setQual((String) record.getValueByKey("qual"));
|
||||
|
||||
data.setHeadingStatus((String) record.getValueByKey("headingStatus"));
|
||||
|
||||
data.setLatitude((String) record.getValueByKey("latitude"));
|
||||
|
||||
data.setLongitude((String) record.getValueByKey("longitude"));
|
||||
|
||||
data.setCuttingSpeed((String) record.getValueByKey("cuttingSpeed"));
|
||||
|
||||
data.setControlMode((String) record.getValueByKey("controlMode"));
|
||||
|
||||
data.setBattery((String) record.getValueByKey("battery"));
|
||||
|
||||
data.setWorkingArea((String) record.getValueByKey("workingArea"));
|
||||
|
||||
data.setObstacleSign((String) record.getValueByKey("obstacleSign"));
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
package com.maibu.influxdb;
|
||||
|
||||
import com.influxdb.query.FluxRecord;
|
||||
import com.influxdb.query.FluxTable;
|
||||
import com.maibu.influxdb.util.InfluxDBUtil;
|
||||
import com.maibu.influxdb.util.InfluxSqlBuilder;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class test {
|
||||
|
||||
|
||||
@Value("${ioTDA.serverIp}")
|
||||
private String serverIp;
|
||||
|
||||
// @Value("${ioTDA.deviceId}")
|
||||
// private String deviceId;
|
||||
|
||||
@Value("${ioTDA.secret}")
|
||||
private String secret;
|
||||
|
||||
@Value("${ioTDA.serviceId}")
|
||||
private String serviceId;
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
String url = "http://localhost:8086";
|
||||
String token = "maibu-token";
|
||||
String org = "maibu";
|
||||
String bucket = "device_data";
|
||||
//
|
||||
// InfluxDBClient client = InfluxDBClientFactory.create(url, token.toCharArray(), org, bucket);
|
||||
//
|
||||
//
|
||||
// WriteApiBlocking writeApi = client.getWriteApiBlocking();
|
||||
|
||||
InfluxDBUtil dbUtil = new InfluxDBUtil(url,token,org,bucket);
|
||||
|
||||
|
||||
DeviceData data = new DeviceData();
|
||||
data.setDeviceId("AGV_001");
|
||||
data.setTemperature(36.522);
|
||||
data.setVoltage(48.222);
|
||||
data.setTime(Instant.now());
|
||||
|
||||
String line = InfluxSqlBuilder.buildLine(data);
|
||||
dbUtil.write(line);
|
||||
|
||||
|
||||
|
||||
Map<String, String> map = InfluxSqlBuilder.buildTagMap(data,DeviceData::getDeviceId);
|
||||
String flux = InfluxSqlBuilder.buildQuery(bucket,bucket,10,map,"temperature");
|
||||
|
||||
List<FluxTable> tables = dbUtil.query(flux);
|
||||
|
||||
for (FluxTable table : tables) {
|
||||
for (FluxRecord record : table.getRecords()) {
|
||||
System.out.println(record.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,15 +14,15 @@ public class InfluxDBUtil {
|
||||
|
||||
private InfluxDBClient client;
|
||||
private WriteApi writeApi;
|
||||
private String bucket;
|
||||
private String org;
|
||||
public String bucket;
|
||||
public String org;
|
||||
|
||||
public InfluxDBUtil(String url, String token, String org, String bucket) {
|
||||
this.client = InfluxDBClientFactory.create(url, token.toCharArray(), org, bucket);
|
||||
this.bucket = bucket;
|
||||
this.org = org;
|
||||
|
||||
// ✅ 异步批量写入(核心)
|
||||
// 异步批量写入(核心)
|
||||
this.writeApi = client.makeWriteApi(
|
||||
WriteOptions.builder()
|
||||
.batchSize(5000) // 每5000条写一次
|
||||
@@ -32,20 +32,20 @@ public class InfluxDBUtil {
|
||||
.build()
|
||||
);
|
||||
|
||||
// ✅ 监听写入成功
|
||||
// 监听写入成功
|
||||
this.writeApi.listenEvents(WriteSuccessEvent.class, event -> {
|
||||
// 可关闭或打debug日志
|
||||
// System.out.println("写入成功");
|
||||
});
|
||||
|
||||
// ✅ 监听异常
|
||||
// 监听异常
|
||||
this.writeApi.listenEvents(WriteErrorEvent.class, event -> {
|
||||
System.err.println("InfluxDB写入失败: " + event.getThrowable().getMessage());
|
||||
});
|
||||
}
|
||||
|
||||
// =========================
|
||||
// ✅ 批量写入(推荐 Line Protocol)
|
||||
// 批量写入(推荐 Line Protocol)
|
||||
// =========================
|
||||
public void writeBatch(List<String> lines) {
|
||||
for (String line : lines) {
|
||||
@@ -54,14 +54,14 @@ public class InfluxDBUtil {
|
||||
}
|
||||
|
||||
// =========================
|
||||
// ✅ 单条写入
|
||||
// 单条写入
|
||||
// =========================
|
||||
public void write(String line) {
|
||||
writeApi.writeRecord(bucket, org, WritePrecision.MS, line);
|
||||
}
|
||||
|
||||
// =========================
|
||||
// ✅ 查询(返回原始结果)
|
||||
// 查询(返回原始结果)
|
||||
// =========================
|
||||
public List<FluxTable> query(String flux) {
|
||||
QueryApi queryApi = client.getQueryApi();
|
||||
@@ -69,7 +69,7 @@ public class InfluxDBUtil {
|
||||
}
|
||||
|
||||
// =========================
|
||||
// ✅ 查询(转List<Map>)
|
||||
// 查询(转List<Map>)
|
||||
// =========================
|
||||
public List<String> queryValues(String flux) {
|
||||
List<String> resultList = new ArrayList<>();
|
||||
@@ -86,14 +86,14 @@ public class InfluxDBUtil {
|
||||
}
|
||||
|
||||
// =========================
|
||||
// ✅ 手动flush(重要)
|
||||
// 手动flush(重要)
|
||||
// =========================
|
||||
public void flush() {
|
||||
writeApi.flush();
|
||||
}
|
||||
|
||||
// =========================
|
||||
// ✅ 关闭资源(必须)
|
||||
// 关闭资源(必须)
|
||||
// =========================
|
||||
public void close() {
|
||||
try {
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.maibu.influxdb.inter.InfluxTime;
|
||||
import com.maibu.influxdb.inter.InfluxMeasurement;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.StringJoiner;
|
||||
@@ -13,6 +14,7 @@ import java.util.StringJoiner;
|
||||
public class InfluxSqlBuilder {
|
||||
/**
|
||||
* 插入语句拼接
|
||||
*
|
||||
* @param obj
|
||||
* @return
|
||||
*/
|
||||
@@ -41,7 +43,8 @@ public class InfluxSqlBuilder {
|
||||
field.setAccessible(true);
|
||||
Object value = field.get(obj);
|
||||
|
||||
if (value == null) continue;
|
||||
if (value == null)
|
||||
continue;
|
||||
|
||||
String key = escapeKey(field.getName());
|
||||
|
||||
@@ -89,49 +92,130 @@ public class InfluxSqlBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// =========================
|
||||
// ✅ 构建 Flux 查询
|
||||
// =========================
|
||||
// public static String buildQuery(
|
||||
// String bucket,
|
||||
// String measurement,
|
||||
// long startHoursAgo,
|
||||
// Map<String, String> tagFilters,
|
||||
// String field) {
|
||||
|
||||
// StringBuilder flux = new StringBuilder();
|
||||
|
||||
// flux.append("from(bucket:\"").append(bucket).append("\")")
|
||||
// .append(" |> range(start: -").append(startHoursAgo).append("h)")
|
||||
// .append(" |> filter(fn: (r) => r._measurement == \"")
|
||||
// .append(measurement).append("\")");
|
||||
|
||||
// // tag过滤
|
||||
// if (tagFilters != null && !tagFilters.isEmpty()) {
|
||||
// for (Map.Entry<String, String> entry : tagFilters.entrySet()) {
|
||||
// flux.append(" |> filter(fn: (r) => r.")
|
||||
// .append(entry.getKey())
|
||||
// .append(" == \"")
|
||||
// .append(entry.getValue())
|
||||
// .append("\")");
|
||||
// }
|
||||
// }
|
||||
|
||||
// // field过滤
|
||||
// if (field != null) {
|
||||
// flux.append(" |> filter(fn: (r) => r._field == \"")
|
||||
// .append(field)
|
||||
// .append("\")");
|
||||
// }
|
||||
|
||||
// // 按时间倒序
|
||||
// flux.append(" |> sort(columns:[\"_time\"], desc:true)");
|
||||
|
||||
// return flux.toString();
|
||||
// }
|
||||
|
||||
public static String buildQuery(
|
||||
String bucket,
|
||||
String measurement,
|
||||
long startSecondsAgo,
|
||||
Map<String, String> tagFilters,
|
||||
String field
|
||||
) {
|
||||
long startHoursAgo,
|
||||
Map<String, ? extends Collection<String>> tagFilters,
|
||||
String field,
|
||||
boolean latestPerDevice,
|
||||
String groupColumn) {
|
||||
|
||||
StringBuilder flux = new StringBuilder();
|
||||
|
||||
flux.append("from(bucket:\"").append(bucket).append("\")")
|
||||
.append(" |> range(start: -").append(startSecondsAgo).append("h)")
|
||||
flux.append("from(bucket:\"")
|
||||
.append(bucket)
|
||||
.append("\")")
|
||||
.append(" |> range(start: -")
|
||||
.append(startHoursAgo)
|
||||
.append("h)")
|
||||
.append(" |> filter(fn: (r) => r._measurement == \"")
|
||||
.append(measurement).append("\")");
|
||||
.append(measurement)
|
||||
.append("\")");
|
||||
|
||||
// tag过滤
|
||||
// Tag过滤
|
||||
if (tagFilters != null && !tagFilters.isEmpty()) {
|
||||
for (Map.Entry<String, String> entry : tagFilters.entrySet()) {
|
||||
flux.append(" |> filter(fn: (r) => r.")
|
||||
.append(entry.getKey())
|
||||
.append(" == \"")
|
||||
.append(entry.getValue())
|
||||
.append("\")");
|
||||
|
||||
for (Map.Entry<String, ? extends Collection<String>> entry : tagFilters.entrySet()) {
|
||||
|
||||
Collection<String> values = entry.getValue();
|
||||
|
||||
if (values == null || values.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
flux.append(" |> filter(fn: (r) => ");
|
||||
|
||||
boolean first = true;
|
||||
|
||||
for (String value : values) {
|
||||
|
||||
if (!first) {
|
||||
flux.append(" or ");
|
||||
}
|
||||
|
||||
flux.append("r.")
|
||||
.append(entry.getKey())
|
||||
.append(" == \"")
|
||||
.append(value)
|
||||
.append("\"");
|
||||
|
||||
first = false;
|
||||
}
|
||||
|
||||
flux.append(")");
|
||||
}
|
||||
}
|
||||
|
||||
// field过滤
|
||||
if (field != null) {
|
||||
// Field过滤
|
||||
if (field != null && !field.isEmpty()) {
|
||||
flux.append(" |> filter(fn: (r) => r._field == \"")
|
||||
.append(field)
|
||||
.append("\")");
|
||||
}
|
||||
|
||||
// 每个设备最新一条
|
||||
if (latestPerDevice) {
|
||||
|
||||
if (groupColumn == null || groupColumn.isEmpty()) {
|
||||
groupColumn = "deviceId";
|
||||
}
|
||||
|
||||
flux.append(" |> group(columns:[\"")
|
||||
.append(groupColumn)
|
||||
.append("\"])")
|
||||
.append(" |> last()");
|
||||
} else {
|
||||
flux.append(" |> sort(columns:[\"_time\"], desc:true)");
|
||||
}
|
||||
|
||||
return flux.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 类的某些属性转换成map
|
||||
*
|
||||
* @param obj
|
||||
* @param functions
|
||||
* @return
|
||||
@@ -139,8 +223,7 @@ public class InfluxSqlBuilder {
|
||||
*/
|
||||
public static <T> Map<String, String> buildTagMap(
|
||||
T obj,
|
||||
SFunction<T, ?>... functions
|
||||
) {
|
||||
SFunction<T, ?>... functions) {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
|
||||
try {
|
||||
@@ -190,5 +273,4 @@ public class InfluxSqlBuilder {
|
||||
return value.toString(); // double/float
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -4,6 +4,8 @@ import java.beans.Introspector;
|
||||
import java.lang.invoke.SerializedLambda;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import com.maibu.influxdb.inter.InfluxMeasurement;
|
||||
|
||||
public class LambdaUtils {
|
||||
|
||||
public static <T> String getFieldName(SFunction<T, ?> fn) {
|
||||
@@ -26,4 +28,16 @@ public class LambdaUtils {
|
||||
throw new RuntimeException("解析字段失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getMeasurement(Class<?> clazz) {
|
||||
|
||||
InfluxMeasurement annotation = clazz.getAnnotation(InfluxMeasurement.class);
|
||||
|
||||
if (annotation == null) {
|
||||
throw new IllegalArgumentException(
|
||||
clazz.getName() + " 未配置 @InfluxMeasurement");
|
||||
}
|
||||
|
||||
return annotation.value();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,30 +1,26 @@
|
||||
package com.maibu.memory;
|
||||
|
||||
|
||||
import com.maibu.core.business.Device;
|
||||
import com.maibu.core.business.IoTCommonDevice;
|
||||
import com.maibu.core.business.IoTCommonProduct;
|
||||
import com.maibu.core.business.uav.IotUAVDevice;
|
||||
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;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import com.maibu.core.business.Device;
|
||||
import com.maibu.core.business.IoTCommonDevice;
|
||||
import com.maibu.core.business.IoTCommonProduct;
|
||||
import com.maibu.influxdb.util.InfluxDBUtil;
|
||||
import com.maibu.mqtt.MqttClientUtil;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Component
|
||||
@Data
|
||||
public class GlobalMemory {
|
||||
|
||||
|
||||
// orgId - siteId - deviceId
|
||||
// public static ConcurrentHashMap<Long, IoTCommonDevice> unRegisterCommonDeviceMap = new ConcurrentHashMap<>();
|
||||
//
|
||||
// public static ConcurrentHashMap<Long, Device> unRegisterDeviceMap = new ConcurrentHashMap<>();
|
||||
|
||||
// orgId - siteId - deviceId
|
||||
public static ConcurrentHashMap<String, IoTCommonDevice> unRegisterCommonDeviceMap = new ConcurrentHashMap<>();
|
||||
|
||||
@@ -35,6 +31,9 @@ public class GlobalMemory {
|
||||
|
||||
public static ConcurrentHashMap<Long, IoTCommonProduct> productMap = new ConcurrentHashMap<>();
|
||||
|
||||
public static InfluxDBUtil influxDBUtil;
|
||||
|
||||
public static MqttClientUtil mqttClientUtil;
|
||||
|
||||
public static SiteMemory getSiteMemory(Long orgId, Long siteId) {
|
||||
if (orgId != null && siteId != null) {
|
||||
@@ -56,11 +55,12 @@ public class GlobalMemory {
|
||||
|
||||
/**
|
||||
* 新增场站内存
|
||||
*
|
||||
* @param orgId
|
||||
* @param siteId
|
||||
* @param siteMemory
|
||||
*/
|
||||
//todo 初始化
|
||||
// todo 初始化
|
||||
public static void addSiteMemory(Long orgId, Long siteId, SiteMemory siteMemory) {
|
||||
|
||||
if (orgId != null && siteId != null) {
|
||||
@@ -75,6 +75,7 @@ public class GlobalMemory {
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*
|
||||
* @param orgId
|
||||
* @param siteId
|
||||
*/
|
||||
|
||||
@@ -1,22 +1,23 @@
|
||||
package com.maibu.memory;
|
||||
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.maibu.core.business.*;
|
||||
import com.maibu.core.business.device.Connector;
|
||||
import com.maibu.core.business.device.NettyDevice;
|
||||
import com.maibu.core.enums.ConnectorStatus;
|
||||
import com.maibu.core.enums.ConnectorType;
|
||||
import io.netty.channel.Channel;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
import com.maibu.core.business.Device;
|
||||
import com.maibu.core.business.DevicePlan;
|
||||
import com.maibu.core.business.DevicePlanTask;
|
||||
import com.maibu.core.business.ErrorIdentificationStandard;
|
||||
import com.maibu.core.business.IoTCommonDevice;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Component
|
||||
@Data
|
||||
|
||||
135
maibu-common/src/main/java/com/maibu/mqtt/MqttClientUtil.java
Normal file
135
maibu-common/src/main/java/com/maibu/mqtt/MqttClientUtil.java
Normal file
@@ -0,0 +1,135 @@
|
||||
package com.maibu.mqtt;
|
||||
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.eclipse.paho.client.mqttv3.*;
|
||||
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
|
||||
|
||||
@Slf4j
|
||||
public class MqttClientUtil {
|
||||
|
||||
private final MqttClient client;
|
||||
|
||||
public MqttClientUtil(
|
||||
String broker,
|
||||
String clientId,
|
||||
String username,
|
||||
String password) throws MqttException {
|
||||
|
||||
this.client = new MqttClient(
|
||||
broker,
|
||||
clientId,
|
||||
new MemoryPersistence());
|
||||
|
||||
MqttConnectOptions options = new MqttConnectOptions();
|
||||
options.setCleanSession(false);
|
||||
options.setAutomaticReconnect(true);
|
||||
options.setConnectionTimeout(10);
|
||||
options.setKeepAliveInterval(60);
|
||||
|
||||
if (username != null) {
|
||||
options.setUserName(username);
|
||||
}
|
||||
|
||||
if (password != null) {
|
||||
options.setPassword(password.toCharArray());
|
||||
}
|
||||
|
||||
client.connect(options);
|
||||
|
||||
log.info("MQTT连接成功: {}", broker);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订阅
|
||||
*/
|
||||
public void subscribe(String topic) throws MqttException {
|
||||
|
||||
client.subscribe(topic);
|
||||
|
||||
log.info("订阅成功: {}", topic);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订阅并监听
|
||||
*/
|
||||
public void subscribe(
|
||||
String topic,
|
||||
IMqttMessageListener listener)
|
||||
throws MqttException {
|
||||
|
||||
client.subscribe(topic, listener);
|
||||
|
||||
log.info("订阅成功: {}", topic);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发布消息
|
||||
*/
|
||||
public void publish(
|
||||
String topic,
|
||||
String payload)
|
||||
throws MqttException {
|
||||
|
||||
publish(topic, payload, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发布消息
|
||||
*/
|
||||
public void publish(
|
||||
String topic,
|
||||
String payload,
|
||||
int qos)
|
||||
throws MqttException {
|
||||
|
||||
MqttMessage message =
|
||||
new MqttMessage(payload.getBytes());
|
||||
|
||||
message.setQos(qos);
|
||||
|
||||
client.publish(topic, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置全局监听器
|
||||
*/
|
||||
public void setCallback() {
|
||||
|
||||
client.setCallback(new MqttCallback() {
|
||||
|
||||
@Override
|
||||
public void connectionLost(Throwable cause) {
|
||||
|
||||
log.error("MQTT断开连接", cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void messageArrived(
|
||||
String topic,
|
||||
MqttMessage message) {
|
||||
|
||||
log.info(
|
||||
"收到消息 topic={} payload={}",
|
||||
topic,
|
||||
new String(message.getPayload()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deliveryComplete(
|
||||
IMqttDeliveryToken token) {
|
||||
|
||||
log.debug("消息发送成功");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public boolean isConnected() {
|
||||
return client.isConnected();
|
||||
}
|
||||
|
||||
public void disconnect() throws MqttException {
|
||||
client.disconnect();
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
10
maibu-common/src/main/java/com/maibu/mqtt/MqttTopic.java
Normal file
10
maibu-common/src/main/java/com/maibu/mqtt/MqttTopic.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package com.maibu.mqtt;
|
||||
|
||||
public class MqttTopic {
|
||||
|
||||
public static final String DEVICE_STATUS_TOPIC = "device/%s/realTimeMessage"; // 实时消息
|
||||
|
||||
public static final String DEVICE_TASK_STATUS_TOPIC = "task/%s/status"; // 任务状态 完成、取消、暂停、继续
|
||||
|
||||
public static final String DEVICE_TASK_ARRIVE_TOPIC = "task/%s/arrive"; // 任务到达
|
||||
}
|
||||
Reference in New Issue
Block a user