|
|
@@ -7,7 +7,6 @@ import com.usky.cdi.domain.DmpDevice;
|
|
|
import com.usky.cdi.domain.DmpProduct;
|
|
|
import com.usky.cdi.mapper.DmpDeviceMapper;
|
|
|
import com.usky.cdi.mapper.DmpProductMapper;
|
|
|
-import com.usky.cdi.service.config.mqtt.MqttBaseConfig;
|
|
|
import com.usky.cdi.service.config.mqtt.MqttOutConfig;
|
|
|
import com.usky.cdi.service.enums.EnvMonitorMqttTopic;
|
|
|
import com.usky.cdi.service.util.DeviceDataQuery;
|
|
|
@@ -18,24 +17,26 @@ import lombok.extern.slf4j.Slf4j;
|
|
|
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
-import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
|
|
import org.springframework.context.ApplicationContext;
|
|
|
-import org.springframework.context.ConfigurableApplicationContext;
|
|
|
+import org.springframework.context.support.GenericApplicationContext;
|
|
|
+import org.springframework.integration.channel.DirectChannel;
|
|
|
+import org.springframework.integration.dsl.IntegrationFlow;
|
|
|
+import org.springframework.integration.dsl.IntegrationFlows;
|
|
|
+import org.springframework.integration.endpoint.EventDrivenConsumer;
|
|
|
import org.springframework.integration.mqtt.core.DefaultMqttPahoClientFactory;
|
|
|
import org.springframework.integration.mqtt.outbound.MqttPahoMessageHandler;
|
|
|
import org.springframework.messaging.MessageChannel;
|
|
|
+import org.springframework.messaging.MessageHandler;
|
|
|
+import org.springframework.messaging.SubscribableChannel;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
-import org.springframework.web.context.ContextLoader;
|
|
|
|
|
|
import javax.annotation.PostConstruct;
|
|
|
|
|
|
import java.time.Instant;
|
|
|
import java.time.LocalDateTime;
|
|
|
import java.time.ZoneId;
|
|
|
-import java.util.ArrayList;
|
|
|
-import java.util.HashMap;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Map;
|
|
|
+import java.util.*;
|
|
|
+import java.util.concurrent.ConcurrentHashMap;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
|
@@ -59,6 +60,10 @@ public class IotDataTransferService {
|
|
|
private static final int KEEP_ALIVE_INTERVAL = 60;
|
|
|
private static final int COMPLETION_TIMEOUT = 5000;
|
|
|
|
|
|
+ // 存储每个任务的MQTT客户端工厂和网关
|
|
|
+ private final Map<String, MqttOutConfig.MqttGateway> mqttGatewayMap = new ConcurrentHashMap<>();
|
|
|
+ private final Map<String, DefaultMqttPahoClientFactory> mqttClientFactoryMap = new ConcurrentHashMap<>();
|
|
|
+
|
|
|
private SnowflakeIdGenerator idGenerator;
|
|
|
|
|
|
@Autowired
|
|
|
@@ -110,7 +115,7 @@ public class IotDataTransferService {
|
|
|
result.put("successCount", 0);
|
|
|
result.put("failureCount", 0);
|
|
|
|
|
|
- if (!validateMqttGateway()) {
|
|
|
+ if (!validateMqttGateway(transferVO.getUsername())) {
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
@@ -154,7 +159,7 @@ public class IotDataTransferService {
|
|
|
vo.setDataEndTime(dataEndTime);
|
|
|
|
|
|
try {
|
|
|
- sendMqttMessage(EnvMonitorMqttTopic.WATER_LEAK, vo, "水浸状态信息");
|
|
|
+ sendMqttMessage(EnvMonitorMqttTopic.WATER_LEAK, vo, "水浸状态信息", transferVO.getUsername());
|
|
|
result.put("successCount", result.get("successCount") + 1);
|
|
|
} catch (Exception e) {
|
|
|
log.warn("设备{}的水浸状态数据推送失败:{}", deviceId, e.getMessage());
|
|
|
@@ -184,7 +189,7 @@ public class IotDataTransferService {
|
|
|
result.put("successCount", 0);
|
|
|
result.put("failureCount", 0);
|
|
|
|
|
|
- if (!validateMqttGateway()) {
|
|
|
+ if (!validateMqttGateway(transferVO.getUsername())) {
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
@@ -229,19 +234,19 @@ public class IotDataTransferService {
|
|
|
try {
|
|
|
switch (deviceType) {
|
|
|
case 707:
|
|
|
- sendTempData(deviceId, dataEndTime, deviceDataItem, engineeringId);
|
|
|
+ sendTempData(deviceId, dataEndTime, deviceDataItem, engineeringId, transferVO.getUsername());
|
|
|
break;
|
|
|
case 708:
|
|
|
- sendHumidityData(deviceId, dataEndTime, deviceDataItem, engineeringId);
|
|
|
+ sendHumidityData(deviceId, dataEndTime, deviceDataItem, engineeringId, transferVO.getUsername());
|
|
|
break;
|
|
|
case 709:
|
|
|
- sendOxygenData(deviceId, dataEndTime, deviceDataItem, engineeringId);
|
|
|
+ sendOxygenData(deviceId, dataEndTime, deviceDataItem, engineeringId, transferVO.getUsername());
|
|
|
break;
|
|
|
case 710:
|
|
|
- sendCo2Data(deviceId, dataEndTime, deviceDataItem, engineeringId);
|
|
|
+ sendCo2Data(deviceId, dataEndTime, deviceDataItem, engineeringId, transferVO.getUsername());
|
|
|
break;
|
|
|
case 711:
|
|
|
- sendCoData(deviceId, dataEndTime, deviceDataItem, engineeringId);
|
|
|
+ sendCoData(deviceId, dataEndTime, deviceDataItem, engineeringId, transferVO.getUsername());
|
|
|
break;
|
|
|
}
|
|
|
} catch (Exception e) {
|
|
|
@@ -278,7 +283,7 @@ public class IotDataTransferService {
|
|
|
result.put("successCount", 0);
|
|
|
result.put("failureCount", 0);
|
|
|
|
|
|
- if (!validateMqttGateway()) {
|
|
|
+ if (!validateMqttGateway(transferVO.getUsername())) {
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
@@ -316,7 +321,7 @@ public class IotDataTransferService {
|
|
|
vo.setSensorValue(0);
|
|
|
|
|
|
try {
|
|
|
- sendMqttMessage(EnvMonitorMqttTopic.PERSON_PRESENCE, vo, "人员闯入情况");
|
|
|
+ sendMqttMessage(EnvMonitorMqttTopic.PERSON_PRESENCE, vo, "人员闯入情况", transferVO.getUsername());
|
|
|
result.put("successCount", result.get("successCount") + 1);
|
|
|
} catch (Exception e) {
|
|
|
log.warn("设备{}的人员闯入情况数据推送失败:{}", deviceId, e.getMessage());
|
|
|
@@ -345,7 +350,7 @@ public class IotDataTransferService {
|
|
|
result.put("successCount", 0);
|
|
|
result.put("failureCount", 0);
|
|
|
|
|
|
- if (!validateMqttGateway()) {
|
|
|
+ if (!validateMqttGateway(transferVO.getUsername())) {
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
@@ -395,7 +400,7 @@ public class IotDataTransferService {
|
|
|
deviceDataItem.getFloat("active_power"));
|
|
|
|
|
|
try {
|
|
|
- sendMqttMessage(EnvMonitorMqttTopic.ELECTRICITY_LOAD, vo, "人防用电负荷情况");
|
|
|
+ sendMqttMessage(EnvMonitorMqttTopic.ELECTRICITY_LOAD, vo, "人防用电负荷情况", transferVO.getUsername());
|
|
|
result.put("successCount", result.get("successCount") + 1);
|
|
|
} catch (Exception e) {
|
|
|
log.warn("设备{}的人防用电负荷情况数据推送失败:{}", deviceId, e.getMessage());
|
|
|
@@ -421,8 +426,9 @@ public class IotDataTransferService {
|
|
|
* @param deviceId 设备ID
|
|
|
* @param dataEndTime 数据结束时间
|
|
|
* @param engineeringID 工程ID
|
|
|
+ * @param username 用户名
|
|
|
**/
|
|
|
- private void sendTempData(Integer deviceId, LocalDateTime dataEndTime, JSONObject deviceDataItem, Long engineeringID) {
|
|
|
+ private void sendTempData(Integer deviceId, LocalDateTime dataEndTime, JSONObject deviceDataItem, Long engineeringID, String username) {
|
|
|
Float value = deviceDataItem.getFloat("wd");
|
|
|
if (value == null) {
|
|
|
log.warn("设备{}的温度数据为空", deviceId);
|
|
|
@@ -435,7 +441,7 @@ public class IotDataTransferService {
|
|
|
tempVO.setPublishTime(getCurrentTime());
|
|
|
tempVO.setSensorValue(value);
|
|
|
tempVO.setDataEndTime(dataEndTime);
|
|
|
- sendMqttMessage(EnvMonitorMqttTopic.TEMP, tempVO, "温度信息");
|
|
|
+ sendMqttMessage(EnvMonitorMqttTopic.TEMP, tempVO, "温度信息", username);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -445,8 +451,9 @@ public class IotDataTransferService {
|
|
|
* @param deviceId 设备ID
|
|
|
* @param dataEndTime 数据结束时间
|
|
|
* @param engineeringID 工程ID
|
|
|
+ * @param username 用户名
|
|
|
**/
|
|
|
- private void sendHumidityData(Integer deviceId, LocalDateTime dataEndTime, JSONObject deviceDataItem, Long engineeringID) {
|
|
|
+ private void sendHumidityData(Integer deviceId, LocalDateTime dataEndTime, JSONObject deviceDataItem, Long engineeringID, String username) {
|
|
|
Float value = deviceDataItem.getFloat("sd");
|
|
|
if (value == null) {
|
|
|
log.warn("设备{}的湿度数据为空", deviceId);
|
|
|
@@ -459,7 +466,7 @@ public class IotDataTransferService {
|
|
|
humidityVO.setPublishTime(getCurrentTime());
|
|
|
humidityVO.setSensorValue(value);
|
|
|
humidityVO.setDataEndTime(dataEndTime);
|
|
|
- sendMqttMessage(EnvMonitorMqttTopic.HUMIDITY, humidityVO, "湿度信息");
|
|
|
+ sendMqttMessage(EnvMonitorMqttTopic.HUMIDITY, humidityVO, "湿度信息", username);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -469,8 +476,9 @@ public class IotDataTransferService {
|
|
|
* @param deviceId 设备ID
|
|
|
* @param dataEndTime 数据结束时间
|
|
|
* @param engineeringID 工程ID
|
|
|
+ * @param username 用户名
|
|
|
**/
|
|
|
- private void sendOxygenData(Integer deviceId, LocalDateTime dataEndTime, JSONObject deviceDataItem, Long engineeringID) {
|
|
|
+ private void sendOxygenData(Integer deviceId, LocalDateTime dataEndTime, JSONObject deviceDataItem, Long engineeringID, String username) {
|
|
|
Float value = deviceDataItem.getFloat("o2");
|
|
|
if (value == null) {
|
|
|
log.warn("设备{}的氧气浓度数据为空", deviceId);
|
|
|
@@ -483,7 +491,7 @@ public class IotDataTransferService {
|
|
|
oxygenVO.setPublishTime(getCurrentTime());
|
|
|
oxygenVO.setSensorValue(value);
|
|
|
oxygenVO.setDataEndTime(dataEndTime);
|
|
|
- sendMqttMessage(EnvMonitorMqttTopic.OXYGEN, oxygenVO, "氧气浓度信息");
|
|
|
+ sendMqttMessage(EnvMonitorMqttTopic.OXYGEN, oxygenVO, "氧气浓度信息", username);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -493,8 +501,9 @@ public class IotDataTransferService {
|
|
|
* @param deviceId 设备ID
|
|
|
* @param dataEndTime 数据结束时间
|
|
|
* @param engineeringID 工程ID
|
|
|
+ * @param username 用户名
|
|
|
**/
|
|
|
- private void sendCoData(Integer deviceId, LocalDateTime dataEndTime, JSONObject deviceDataItem, Long engineeringID) {
|
|
|
+ private void sendCoData(Integer deviceId, LocalDateTime dataEndTime, JSONObject deviceDataItem, Long engineeringID, String username) {
|
|
|
Float value = deviceDataItem.getFloat("co");
|
|
|
if (value == null) {
|
|
|
log.warn("设备{}的一氧化碳浓度数据为空", deviceId);
|
|
|
@@ -507,7 +516,7 @@ public class IotDataTransferService {
|
|
|
coVO.setPublishTime(getCurrentTime());
|
|
|
coVO.setSensorValue(value);
|
|
|
coVO.setDataEndTime(dataEndTime);
|
|
|
- sendMqttMessage(EnvMonitorMqttTopic.CO, coVO, "一氧化碳浓度信息");
|
|
|
+ sendMqttMessage(EnvMonitorMqttTopic.CO, coVO, "一氧化碳浓度信息", username);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -517,8 +526,9 @@ public class IotDataTransferService {
|
|
|
* @param deviceId 设备ID
|
|
|
* @param dataEndTime 数据结束时间
|
|
|
* @param engineeringID 工程ID
|
|
|
+ * @param username 用户名
|
|
|
**/
|
|
|
- private void sendCo2Data(Integer deviceId, LocalDateTime dataEndTime, JSONObject deviceDataItem, Long engineeringID) {
|
|
|
+ private void sendCo2Data(Integer deviceId, LocalDateTime dataEndTime, JSONObject deviceDataItem, Long engineeringID, String username) {
|
|
|
Float value = deviceDataItem.getFloat("co2");
|
|
|
if (value == null) {
|
|
|
log.warn("设备{}的二氧化碳浓度数据为空", deviceId);
|
|
|
@@ -531,7 +541,7 @@ public class IotDataTransferService {
|
|
|
co2VO.setPublishTime(getCurrentTime());
|
|
|
co2VO.setSensorValue(value);
|
|
|
co2VO.setDataEndTime(dataEndTime);
|
|
|
- sendMqttMessage(EnvMonitorMqttTopic.CO2, co2VO, "二氧化碳浓度信息");
|
|
|
+ sendMqttMessage(EnvMonitorMqttTopic.CO2, co2VO, "二氧化碳浓度信息", username);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -539,144 +549,144 @@ public class IotDataTransferService {
|
|
|
*
|
|
|
* @return 推送结果,包含成功数和失败数
|
|
|
**/
|
|
|
- public Map<String, Integer> sendTiltData(IotDataTransferVO transferVO) {
|
|
|
- Map<String, Integer> result = new HashMap<>();
|
|
|
- result.put("successCount", 0);
|
|
|
- result.put("failureCount", 0);
|
|
|
-
|
|
|
- if (!validateMqttGateway()) {
|
|
|
- return result;
|
|
|
- }
|
|
|
-
|
|
|
- try {
|
|
|
- List<JSONObject> deviceData = deviceDataQuery.getDeviceData(transferVO);
|
|
|
- Integer deviceType = transferVO.getDeviceType();
|
|
|
- Integer totalDevices = transferVO.getDevices().size();
|
|
|
-
|
|
|
- log.info("开始推送倾斜数据,设备类型:{},设备数量:{},获取到的数据条数:{}",
|
|
|
- deviceType, totalDevices, deviceData.size());
|
|
|
-
|
|
|
- if (deviceData.isEmpty()) {
|
|
|
- log.warn("没有获取到倾斜数据!设备类型:{}", deviceType);
|
|
|
- result.put("failureCount", totalDevices);
|
|
|
- return result;
|
|
|
- }
|
|
|
-
|
|
|
- Long engineeringId = transferVO.getEngineeringId();
|
|
|
- for (JSONObject deviceDataItem : deviceData) {
|
|
|
- LocalDateTime dataEndTime = parseDataTime(deviceDataItem);
|
|
|
- if (dataEndTime == null) {
|
|
|
- result.put("failureCount", result.get("failureCount") + 1);
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- Integer deviceId = deviceDataItem.getIntValue("device_id");
|
|
|
- Integer value = deviceDataItem.getInteger("qx");
|
|
|
- if (value == null) {
|
|
|
- log.warn("设备{}的倾斜数据为空", deviceId);
|
|
|
- result.put("failureCount", result.get("failureCount") + 1);
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- TiltVO vo = new TiltVO();
|
|
|
- vo.setDataPacketID(generateDataPacketID());
|
|
|
- vo.setSensorID(deviceId);
|
|
|
- vo.setEngineeringID(engineeringId);
|
|
|
- vo.setPublishTime(getCurrentTime());
|
|
|
- vo.setDataEndTime(dataEndTime);
|
|
|
- vo.setSensorValue(value == 0 ? 0 : 1);
|
|
|
-
|
|
|
- try {
|
|
|
- sendMqttMessage(EnvMonitorMqttTopic.TILT, vo, "倾斜信息");
|
|
|
- result.put("successCount", result.get("successCount") + 1);
|
|
|
- } catch (Exception e) {
|
|
|
- log.warn("设备{}的倾斜数据推送失败:{}", deviceId, e.getMessage());
|
|
|
- result.put("failureCount", result.get("failureCount") + 1);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- log.info("倾斜数据推送完成,设备类型:{},成功:{},失败:{}",
|
|
|
- deviceType, result.get("successCount"), result.get("failureCount"));
|
|
|
-
|
|
|
- return result;
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("倾斜数据推送发生异常", e);
|
|
|
- result.put("failureCount", transferVO.getDevices().size());
|
|
|
- return result;
|
|
|
- }
|
|
|
- }
|
|
|
+ // public Map<String, Integer> sendTiltData(IotDataTransferVO transferVO) {
|
|
|
+ // Map<String, Integer> result = new HashMap<>();
|
|
|
+ // result.put("successCount", 0);
|
|
|
+ // result.put("failureCount", 0);
|
|
|
+ //
|
|
|
+ // if (!validateMqttGateway()) {
|
|
|
+ // return result;
|
|
|
+ // }
|
|
|
+ //
|
|
|
+ // try {
|
|
|
+ // List<JSONObject> deviceData = deviceDataQuery.getDeviceData(transferVO);
|
|
|
+ // Integer deviceType = transferVO.getDeviceType();
|
|
|
+ // Integer totalDevices = transferVO.getDevices().size();
|
|
|
+ //
|
|
|
+ // log.info("开始推送倾斜数据,设备类型:{},设备数量:{},获取到的数据条数:{}",
|
|
|
+ // deviceType, totalDevices, deviceData.size());
|
|
|
+ //
|
|
|
+ // if (deviceData.isEmpty()) {
|
|
|
+ // log.warn("没有获取到倾斜数据!设备类型:{}", deviceType);
|
|
|
+ // result.put("failureCount", totalDevices);
|
|
|
+ // return result;
|
|
|
+ // }
|
|
|
+ //
|
|
|
+ // Long engineeringId = transferVO.getEngineeringId();
|
|
|
+ // for (JSONObject deviceDataItem : deviceData) {
|
|
|
+ // LocalDateTime dataEndTime = parseDataTime(deviceDataItem);
|
|
|
+ // if (dataEndTime == null) {
|
|
|
+ // result.put("failureCount", result.get("failureCount") + 1);
|
|
|
+ // continue;
|
|
|
+ // }
|
|
|
+ //
|
|
|
+ // Integer deviceId = deviceDataItem.getIntValue("device_id");
|
|
|
+ // Integer value = deviceDataItem.getInteger("qx");
|
|
|
+ // if (value == null) {
|
|
|
+ // log.warn("设备{}的倾斜数据为空", deviceId);
|
|
|
+ // result.put("failureCount", result.get("failureCount") + 1);
|
|
|
+ // continue;
|
|
|
+ // }
|
|
|
+ //
|
|
|
+ // TiltVO vo = new TiltVO();
|
|
|
+ // vo.setDataPacketID(generateDataPacketID());
|
|
|
+ // vo.setSensorID(deviceId);
|
|
|
+ // vo.setEngineeringID(engineeringId);
|
|
|
+ // vo.setPublishTime(getCurrentTime());
|
|
|
+ // vo.setDataEndTime(dataEndTime);
|
|
|
+ // vo.setSensorValue(value == 0 ? 0 : 1);
|
|
|
+ //
|
|
|
+ // try {
|
|
|
+ // sendMqttMessage(EnvMonitorMqttTopic.TILT, vo, "倾斜信息");
|
|
|
+ // result.put("successCount", result.get("successCount") + 1);
|
|
|
+ // } catch (Exception e) {
|
|
|
+ // log.warn("设备{}的倾斜数据推送失败:{}", deviceId, e.getMessage());
|
|
|
+ // result.put("failureCount", result.get("failureCount") + 1);
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ //
|
|
|
+ // log.info("倾斜数据推送完成,设备类型:{},成功:{},失败:{}",
|
|
|
+ // deviceType, result.get("successCount"), result.get("failureCount"));
|
|
|
+ //
|
|
|
+ // return result;
|
|
|
+ // } catch (Exception e) {
|
|
|
+ // log.error("倾斜数据推送发生异常", e);
|
|
|
+ // result.put("failureCount", transferVO.getDevices().size());
|
|
|
+ // return result;
|
|
|
+ // }
|
|
|
+ // }
|
|
|
|
|
|
/**
|
|
|
* 发送裂缝数据(713)
|
|
|
*
|
|
|
* @return 推送结果,包含成功数和失败数
|
|
|
**/
|
|
|
- public Map<String, Integer> sendCrackData(IotDataTransferVO transferVO) {
|
|
|
- Map<String, Integer> result = new HashMap<>();
|
|
|
- result.put("successCount", 0);
|
|
|
- result.put("failureCount", 0);
|
|
|
-
|
|
|
- if (!validateMqttGateway()) {
|
|
|
- return result;
|
|
|
- }
|
|
|
-
|
|
|
- try {
|
|
|
- List<JSONObject> deviceData = deviceDataQuery.getDeviceData(transferVO);
|
|
|
- Integer deviceType = transferVO.getDeviceType();
|
|
|
- Integer totalDevices = transferVO.getDevices().size();
|
|
|
-
|
|
|
- log.info("开始推送裂缝数据,设备类型:{},设备数量:{},获取到的数据条数:{}",
|
|
|
- deviceType, totalDevices, deviceData.size());
|
|
|
-
|
|
|
- if (deviceData.isEmpty()) {
|
|
|
- log.warn("没有获取到裂缝数据!设备类型:{}", deviceType);
|
|
|
- result.put("failureCount", totalDevices);
|
|
|
- return result;
|
|
|
- }
|
|
|
-
|
|
|
- Long engineeringId = transferVO.getEngineeringId();
|
|
|
- for (JSONObject deviceDataItem : deviceData) {
|
|
|
- LocalDateTime dataEndTime = parseDataTime(deviceDataItem);
|
|
|
- if (dataEndTime == null) {
|
|
|
- result.put("failureCount", result.get("failureCount") + 1);
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- Integer deviceId = deviceDataItem.getIntValue("device_id");
|
|
|
- Integer value = deviceDataItem.getInteger("cd");
|
|
|
- if (value == null) {
|
|
|
- log.warn("设备{}的裂缝数据为空", deviceId);
|
|
|
- result.put("failureCount", result.get("failureCount") + 1);
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- CrackVO vo = new CrackVO();
|
|
|
- vo.setDataPacketID(generateDataPacketID());
|
|
|
- vo.setSensorID(deviceId);
|
|
|
- vo.setEngineeringID(engineeringId);
|
|
|
- vo.setPublishTime(getCurrentTime());
|
|
|
- vo.setDataEndTime(dataEndTime);
|
|
|
- vo.setSensorValue(value == 0 ? 0 : 1);
|
|
|
-
|
|
|
- try {
|
|
|
- sendMqttMessage(EnvMonitorMqttTopic.CRACK, vo, "裂缝信息");
|
|
|
- result.put("successCount", result.get("successCount") + 1);
|
|
|
- } catch (Exception e) {
|
|
|
- log.warn("设备{}的裂缝数据推送失败:{}", deviceId, e.getMessage());
|
|
|
- result.put("failureCount", result.get("failureCount") + 1);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- log.info("裂缝数据推送完成,设备类型:{},成功:{},失败:{}",
|
|
|
- deviceType, result.get("successCount"), result.get("failureCount"));
|
|
|
-
|
|
|
- return result;
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("裂缝数据推送发生异常", e);
|
|
|
- result.put("failureCount", transferVO.getDevices().size());
|
|
|
- return result;
|
|
|
- }
|
|
|
- }
|
|
|
+ // public Map<String, Integer> sendCrackData(IotDataTransferVO transferVO) {
|
|
|
+ // Map<String, Integer> result = new HashMap<>();
|
|
|
+ // result.put("successCount", 0);
|
|
|
+ // result.put("failureCount", 0);
|
|
|
+ //
|
|
|
+ // if (!validateMqttGateway()) {
|
|
|
+ // return result;
|
|
|
+ // }
|
|
|
+ //
|
|
|
+ // try {
|
|
|
+ // List<JSONObject> deviceData = deviceDataQuery.getDeviceData(transferVO);
|
|
|
+ // Integer deviceType = transferVO.getDeviceType();
|
|
|
+ // Integer totalDevices = transferVO.getDevices().size();
|
|
|
+ //
|
|
|
+ // log.info("开始推送裂缝数据,设备类型:{},设备数量:{},获取到的数据条数:{}",
|
|
|
+ // deviceType, totalDevices, deviceData.size());
|
|
|
+ //
|
|
|
+ // if (deviceData.isEmpty()) {
|
|
|
+ // log.warn("没有获取到裂缝数据!设备类型:{}", deviceType);
|
|
|
+ // result.put("failureCount", totalDevices);
|
|
|
+ // return result;
|
|
|
+ // }
|
|
|
+ //
|
|
|
+ // Long engineeringId = transferVO.getEngineeringId();
|
|
|
+ // for (JSONObject deviceDataItem : deviceData) {
|
|
|
+ // LocalDateTime dataEndTime = parseDataTime(deviceDataItem);
|
|
|
+ // if (dataEndTime == null) {
|
|
|
+ // result.put("failureCount", result.get("failureCount") + 1);
|
|
|
+ // continue;
|
|
|
+ // }
|
|
|
+ //
|
|
|
+ // Integer deviceId = deviceDataItem.getIntValue("device_id");
|
|
|
+ // Integer value = deviceDataItem.getInteger("cd");
|
|
|
+ // if (value == null) {
|
|
|
+ // log.warn("设备{}的裂缝数据为空", deviceId);
|
|
|
+ // result.put("failureCount", result.get("failureCount") + 1);
|
|
|
+ // continue;
|
|
|
+ // }
|
|
|
+ //
|
|
|
+ // CrackVO vo = new CrackVO();
|
|
|
+ // vo.setDataPacketID(generateDataPacketID());
|
|
|
+ // vo.setSensorID(deviceId);
|
|
|
+ // vo.setEngineeringID(engineeringId);
|
|
|
+ // vo.setPublishTime(getCurrentTime());
|
|
|
+ // vo.setDataEndTime(dataEndTime);
|
|
|
+ // vo.setSensorValue(value == 0 ? 0 : 1);
|
|
|
+ //
|
|
|
+ // try {
|
|
|
+ // sendMqttMessage(EnvMonitorMqttTopic.CRACK, vo, "裂缝信息");
|
|
|
+ // result.put("successCount", result.get("successCount") + 1);
|
|
|
+ // } catch (Exception e) {
|
|
|
+ // log.warn("设备{}的裂缝数据推送失败:{}", deviceId, e.getMessage());
|
|
|
+ // result.put("failureCount", result.get("failureCount") + 1);
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ //
|
|
|
+ // log.info("裂缝数据推送完成,设备类型:{},成功:{},失败:{}",
|
|
|
+ // deviceType, result.get("successCount"), result.get("failureCount"));
|
|
|
+ //
|
|
|
+ // return result;
|
|
|
+ // } catch (Exception e) {
|
|
|
+ // log.error("裂缝数据推送发生异常", e);
|
|
|
+ // result.put("failureCount", transferVO.getDevices().size());
|
|
|
+ // return result;
|
|
|
+ // }
|
|
|
+ // }
|
|
|
|
|
|
/**
|
|
|
* 发送位移数据(714)
|
|
|
@@ -688,7 +698,7 @@ public class IotDataTransferService {
|
|
|
result.put("successCount", 0);
|
|
|
result.put("failureCount", 0);
|
|
|
|
|
|
- if (!validateMqttGateway()) {
|
|
|
+ if (!validateMqttGateway(transferVO.getUsername())) {
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
@@ -731,7 +741,7 @@ public class IotDataTransferService {
|
|
|
vo.setSensorValue(value == 0 ? 0 : 1);
|
|
|
|
|
|
try {
|
|
|
- sendMqttMessage(EnvMonitorMqttTopic.DEVIATION, vo, "位移信息");
|
|
|
+ sendMqttMessage(EnvMonitorMqttTopic.DEVIATION, vo, "位移信息", transferVO.getUsername());
|
|
|
result.put("successCount", result.get("successCount") + 1);
|
|
|
} catch (Exception e) {
|
|
|
log.warn("设备{}的位移数据推送失败:{}", deviceId, e.getMessage());
|
|
|
@@ -789,6 +799,7 @@ public class IotDataTransferService {
|
|
|
transferVO.setDeviceType(deviceType);
|
|
|
transferVO.setDevices(devices);
|
|
|
transferVO.setEngineeringId(engineeringId);
|
|
|
+ transferVO.setUsername(username); // 保存当前任务的用户名
|
|
|
transferList.add(transferVO);
|
|
|
});
|
|
|
|
|
|
@@ -839,12 +850,12 @@ public class IotDataTransferService {
|
|
|
case 704:
|
|
|
result = sendElectricityLoad(transferVO);
|
|
|
break;
|
|
|
- case 712:
|
|
|
- result = sendTiltData(transferVO);
|
|
|
- break;
|
|
|
- case 713:
|
|
|
- result = sendCrackData(transferVO);
|
|
|
- break;
|
|
|
+ // case 712:
|
|
|
+ // result = sendTiltData(transferVO);
|
|
|
+ // break;
|
|
|
+ // case 713:
|
|
|
+ // result = sendCrackData(transferVO);
|
|
|
+ // break;
|
|
|
case 714:
|
|
|
result = sendDeviationData(transferVO);
|
|
|
break;
|
|
|
@@ -899,42 +910,78 @@ public class IotDataTransferService {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 手动创建MQTT连接
|
|
|
+ * 手动创建/刷新 MQTT 连接(含动态 clientId)
|
|
|
* @param username MQTT用户名
|
|
|
* @param password MQTT密码
|
|
|
*/
|
|
|
public void createMqttConnection(String username, String password) {
|
|
|
try {
|
|
|
- // 使用注入的ApplicationContext获取已有的mqttGateway实例
|
|
|
- // 因为我们保留了@MessagingGateway注解,Spring会自动创建这个实例
|
|
|
+ // 使用注入的ApplicationContext获取或创建MQTT连接
|
|
|
if (this.context == null) {
|
|
|
throw new IllegalStateException("ApplicationContext未注入,无法获取MQTT Gateway");
|
|
|
}
|
|
|
|
|
|
- // 1. 获取mqttGateway实例
|
|
|
- this.mqttGateway = this.context.getBean(MqttOutConfig.MqttGateway.class);
|
|
|
- if (this.mqttGateway == null) {
|
|
|
- throw new IllegalStateException("MQTT Gateway未找到,无法发送消息");
|
|
|
- }
|
|
|
+ // 检查是否已经为该用户创建了MQTT连接
|
|
|
+ if (!mqttGatewayMap.containsKey(username)) {
|
|
|
+ synchronized (this) {
|
|
|
+ // 双重检查锁定
|
|
|
+ if (!mqttGatewayMap.containsKey(username)) {
|
|
|
+ // 1. 创建新的MQTT客户端工厂
|
|
|
+ DefaultMqttPahoClientFactory mqttClientFactory = new DefaultMqttPahoClientFactory();
|
|
|
|
|
|
- // 2. 获取现有的mqttClientFactory实例
|
|
|
- DefaultMqttPahoClientFactory mqttClientFactory = this.context.getBean(DefaultMqttPahoClientFactory.class);
|
|
|
- if (mqttClientFactory == null) {
|
|
|
- throw new IllegalStateException("MQTT Client Factory未找到,无法创建MQTT连接");
|
|
|
- }
|
|
|
+ // 2. 创建并配置MqttConnectOptions
|
|
|
+ MqttConnectOptions options = new MqttConnectOptions();
|
|
|
+ options.setServerURIs(new String[]{MQTT_URL});
|
|
|
+ options.setUserName(username);
|
|
|
+ options.setPassword(password.toCharArray());
|
|
|
+ options.setKeepAliveInterval(KEEP_ALIVE_INTERVAL);
|
|
|
+
|
|
|
+ // 3. 设置连接选项
|
|
|
+ mqttClientFactory.setConnectionOptions(options);
|
|
|
+
|
|
|
+ // 4. 创建唯一的客户端ID
|
|
|
+ String clientId = "mqttx-" + username;
|
|
|
+
|
|
|
+ // 5. 创建MQTT消息处理器
|
|
|
+ MqttPahoMessageHandler messageHandler = new MqttPahoMessageHandler(clientId, mqttClientFactory);
|
|
|
+ messageHandler.setAsync(true);
|
|
|
+ messageHandler.setDefaultTopic("testTopic");
|
|
|
+
|
|
|
+ // 6. 获取消息通道
|
|
|
+ MessageChannel mqttOutboundChannel = context.getBean("mqttOutboundChannel", MessageChannel.class);
|
|
|
|
|
|
- // 3. 创建并配置MqttConnectOptions
|
|
|
- MqttConnectOptions options = new MqttConnectOptions();
|
|
|
- options.setServerURIs(new String[]{MQTT_URL});
|
|
|
- options.setUserName(username);
|
|
|
- options.setPassword(password.toCharArray());
|
|
|
- options.setKeepAliveInterval(KEEP_ALIVE_INTERVAL);
|
|
|
+ // 7. 注册消息处理器到通道
|
|
|
+ IntegrationFlow flow = IntegrationFlows.from(mqttOutboundChannel)
|
|
|
+ .handle(messageHandler)
|
|
|
+ .get();
|
|
|
|
|
|
- // 4. 更新mqttClientFactory的连接选项
|
|
|
- mqttClientFactory.setConnectionOptions(options);
|
|
|
+ // 8. 注册IntegrationFlow
|
|
|
+ ((GenericApplicationContext) context).registerBean("mqttFlow-" + username, IntegrationFlow.class, () -> flow);
|
|
|
+ ((GenericApplicationContext) context).refresh();
|
|
|
|
|
|
- log.info("MQTT Gateway初始化成功,用户名:{}", username);
|
|
|
- log.info("MQTT连接配置完成,服务器地址:{},客户端ID:mqttx-{}", MQTT_URL, username);
|
|
|
+ // 9. 获取MQTT Gateway实例
|
|
|
+ MqttOutConfig.MqttGateway mqttGateway = context.getBean(MqttOutConfig.MqttGateway.class);
|
|
|
+
|
|
|
+ // 10. 存储到映射中
|
|
|
+ mqttGatewayMap.put(username, mqttGateway);
|
|
|
+ mqttClientFactoryMap.put(username, mqttClientFactory);
|
|
|
+
|
|
|
+ log.info("MQTT连接创建成功,用户名:{},客户端ID:{}", username, clientId);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 连接已存在,更新密码
|
|
|
+ DefaultMqttPahoClientFactory clientFactory = mqttClientFactoryMap.get(username);
|
|
|
+ if (clientFactory != null) {
|
|
|
+ MqttConnectOptions options = new MqttConnectOptions();
|
|
|
+ options.setServerURIs(new String[]{MQTT_URL});
|
|
|
+ options.setUserName(username);
|
|
|
+ options.setPassword(password.toCharArray());
|
|
|
+ options.setKeepAliveInterval(KEEP_ALIVE_INTERVAL);
|
|
|
+ clientFactory.setConnectionOptions(options);
|
|
|
+ log.info("MQTT连接密码已更新,用户名:{}", username);
|
|
|
+ }
|
|
|
+ }
|
|
|
} catch (Exception e) {
|
|
|
log.error("初始化MQTT连接失败: {}", e.getMessage(), e);
|
|
|
throw new RuntimeException("初始化MQTT连接失败", e);
|
|
|
@@ -943,11 +990,12 @@ public class IotDataTransferService {
|
|
|
|
|
|
/**
|
|
|
* 验证MQTT网关是否初始化
|
|
|
+ * @param username 用户名
|
|
|
* @return 是否初始化
|
|
|
*/
|
|
|
- private boolean validateMqttGateway() {
|
|
|
- if (mqttGateway == null) {
|
|
|
- log.warn("MQTT Gateway未初始化,无法发送消息");
|
|
|
+ private boolean validateMqttGateway(String username) {
|
|
|
+ if (username == null || !mqttGatewayMap.containsKey(username) || mqttGatewayMap.get(username) == null) {
|
|
|
+ log.warn("MQTT Gateway未初始化,无法发送消息,用户名:{}", username);
|
|
|
return false;
|
|
|
}
|
|
|
return true;
|
|
|
@@ -973,12 +1021,18 @@ public class IotDataTransferService {
|
|
|
* @param topicEnum 主题枚举
|
|
|
* @param vo 消息对象
|
|
|
* @param messageType 消息类型描述
|
|
|
+ * @param username 用户名
|
|
|
*/
|
|
|
- private void sendMqttMessage(EnvMonitorMqttTopic topicEnum, Object vo, String messageType) {
|
|
|
+ private void sendMqttMessage(EnvMonitorMqttTopic topicEnum, Object vo, String messageType, String username) {
|
|
|
String json = JSON.toJSONString(vo);
|
|
|
String topic = topicEnum.getTopic();
|
|
|
// 不再记录每条数据的详情,只记录发送操作
|
|
|
- mqttGateway.sendToMqtt(topic, json);
|
|
|
+ MqttOutConfig.MqttGateway gateway = mqttGatewayMap.get(username);
|
|
|
+ if (gateway != null) {
|
|
|
+ gateway.sendToMqtt(topic, json);
|
|
|
+ } else {
|
|
|
+ log.warn("MQTT Gateway未找到,无法发送消息,用户名:{}", username);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
public void allData(Long engineeringId, String username, String password) {
|