|
|
@@ -0,0 +1,202 @@
|
|
|
+package com.usky.cdi.service.util;
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
+import com.alibaba.fastjson.JSONArray;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.usky.cdi.domain.DmpDevice;
|
|
|
+import com.usky.cdi.mapper.DmpDeviceMapper;
|
|
|
+import lombok.Data;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
+import org.springframework.boot.context.properties.ConfigurationProperties;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ * @author fyc
|
|
|
+ * @email yuchuan.fu@chinausky.com
|
|
|
+ * @date 2025/11/27
|
|
|
+ */
|
|
|
+@Data
|
|
|
+@Slf4j
|
|
|
+@Component
|
|
|
+@ConfigurationProperties(prefix = "device")
|
|
|
+public class DeviceDataQuery {
|
|
|
+ @Autowired
|
|
|
+ private DmpDeviceMapper dmpDeviceMapper;
|
|
|
+ @Value("${device.data.base-url}")
|
|
|
+ private String baseUrl;
|
|
|
+ @Value("${device.data.simulation}")
|
|
|
+ private boolean simulation;
|
|
|
+ private Map<String, String> deviceFieldMapping;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取指定设备类型的设备数据
|
|
|
+ */
|
|
|
+ public List<JSONObject> getDeviceData(Integer deviceType) {
|
|
|
+ List<String> deviceUuids = getDeviceUuids(deviceType);
|
|
|
+ if (deviceUuids.isEmpty()) {
|
|
|
+ log.warn("该租户下没有注册设备!");
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+
|
|
|
+ JSONObject requestBody = new JSONObject();
|
|
|
+ requestBody.put("deviceUuids", deviceUuids);
|
|
|
+
|
|
|
+ String response = HttpClientUtils.doPostJson(baseUrl, String.valueOf(requestBody));
|
|
|
+
|
|
|
+ List<JSONObject> resultList = parseResponseData(response, deviceType);
|
|
|
+
|
|
|
+ if (resultList.isEmpty() && simulation) {
|
|
|
+ resultList = generateSimulationData(deviceType, deviceUuids);
|
|
|
+ }
|
|
|
+
|
|
|
+ return resultList;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取指定设备类型的设备UUID列表
|
|
|
+ */
|
|
|
+ private List<String> getDeviceUuids(Integer deviceType) {
|
|
|
+ LambdaQueryWrapper<DmpDevice> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ queryWrapper.eq(DmpDevice::getTenantId, 1208)
|
|
|
+ .eq(deviceType != null, DmpDevice::getDeviceType, deviceType);
|
|
|
+ List<DmpDevice> dmpDevices = dmpDeviceMapper.selectList(queryWrapper);
|
|
|
+ return dmpDevices.stream().map(DmpDevice::getDeviceUuid).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 解析接口响应数据,提取指定字段
|
|
|
+ */
|
|
|
+ private List<JSONObject> parseResponseData(String responseJson, Integer deviceType) {
|
|
|
+ List<JSONObject> resultList = new ArrayList<>();
|
|
|
+ if (responseJson == null) {
|
|
|
+ return resultList;
|
|
|
+ }
|
|
|
+
|
|
|
+ JSONObject responseObj = JSON.parseObject(responseJson);
|
|
|
+ if (!"SUCCESS".equals(responseObj.getString("status")) || !"0".equals(responseObj.getString("code"))) {
|
|
|
+ System.err.println("接口返回失败:" + responseObj.getString("msg"));
|
|
|
+ return resultList;
|
|
|
+ }
|
|
|
+
|
|
|
+ JSONArray dataArray = responseObj.getJSONArray("data");
|
|
|
+ if (dataArray == null || dataArray.isEmpty()) {
|
|
|
+ return resultList;
|
|
|
+ }
|
|
|
+
|
|
|
+ List<String> targetFields = getTargetFieldsByDeviceType(deviceType);
|
|
|
+
|
|
|
+ for (int i = 0; i < dataArray.size(); i++) {
|
|
|
+ JSONObject deviceData = dataArray.getJSONObject(i);
|
|
|
+ JSONObject metrics = deviceData.getJSONObject("metrics");
|
|
|
+ String deviceUuid = deviceData.getString("deviceuuid");
|
|
|
+
|
|
|
+ if (metrics == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ JSONObject targetData = new JSONObject();
|
|
|
+ boolean hasValidData = false;
|
|
|
+ for (String field : targetFields) {
|
|
|
+ Object value = metrics.get(field);
|
|
|
+ if (value != null) {
|
|
|
+ targetData.put(field, value);
|
|
|
+ hasValidData = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ targetData.put("deviceuuid", deviceUuid);
|
|
|
+ if (hasValidData) {
|
|
|
+ resultList.add(targetData);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return resultList;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据设备类型获取目标字段(自动包含time)
|
|
|
+ */
|
|
|
+ private List<String> getTargetFieldsByDeviceType(Integer deviceType) {
|
|
|
+ String fieldsStr = deviceFieldMapping.get(deviceType.toString());
|
|
|
+ List<String> fields = Arrays.stream(fieldsStr.split(","))
|
|
|
+ .map(String::trim)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ if (!fields.contains("time")) {
|
|
|
+ fields.add("time");
|
|
|
+ }
|
|
|
+ return fields;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成模拟数据
|
|
|
+ */
|
|
|
+ private List<JSONObject> generateSimulationData(Integer deviceType, List<String> deviceUuids) {
|
|
|
+ List<JSONObject> simulationList = new ArrayList<>();
|
|
|
+ long currentTime = System.currentTimeMillis();
|
|
|
+
|
|
|
+ for (String deviceUuid : deviceUuids) {
|
|
|
+ JSONObject simulationData = new JSONObject();
|
|
|
+ simulationData.put("deviceuuid", deviceUuid);
|
|
|
+ simulationData.put("time", currentTime);
|
|
|
+
|
|
|
+ switch (deviceType) {
|
|
|
+ // 空气质量
|
|
|
+ case 701:
|
|
|
+ simulationData.put("wd", new Random().nextInt(50) - 10); // 温度:-10~40℃
|
|
|
+ simulationData.put("sd", new Random().nextInt(101)); // 湿度:0~100%
|
|
|
+ simulationData.put("o2", new Random().nextDouble() * 21); // 氧气:0~21%
|
|
|
+ simulationData.put("co", new Random().nextDouble() * 100); // 一氧化碳:0~100ppm
|
|
|
+ simulationData.put("co2", new Random().nextDouble() * 2000); // 二氧化碳:0~2000ppm
|
|
|
+ break;
|
|
|
+ // 水浸
|
|
|
+ case 702:
|
|
|
+ // 渗漏状态:0-正常,1-渗漏
|
|
|
+ simulationData.put("leach_status", new Random().nextInt(2));
|
|
|
+ break;
|
|
|
+ // 人员统计
|
|
|
+ case 703:
|
|
|
+ // 流量数据:模拟正数
|
|
|
+ simulationData.put("amount_into", new Random().nextDouble() * 1000);
|
|
|
+ simulationData.put("amount_out", new Random().nextDouble() * 1000);
|
|
|
+ simulationData.put("day_into", new Random().nextDouble() * 10000);
|
|
|
+ simulationData.put("day_out", new Random().nextDouble() * 10000);
|
|
|
+ break;
|
|
|
+ // 电气火灾
|
|
|
+ case 704:
|
|
|
+ // 电气参数:模拟合理范围
|
|
|
+ simulationData.put("voltage_a", 220 + new Random().nextDouble() * 10); // 电压A:220~230V
|
|
|
+ simulationData.put("voltage_b", 220 + new Random().nextDouble() * 10);
|
|
|
+ simulationData.put("voltage_c", 220 + new Random().nextDouble() * 10);
|
|
|
+ simulationData.put("current_a", new Random().nextDouble() * 50); // 电流A:0~50A
|
|
|
+ simulationData.put("current_b", new Random().nextDouble() * 50);
|
|
|
+ simulationData.put("current_c", new Random().nextDouble() * 50);
|
|
|
+ simulationData.put("temperature_a", 20 + new Random().nextDouble() * 30); // 温度A:20~50℃
|
|
|
+ simulationData.put("temperature_b", 20 + new Random().nextDouble() * 30);
|
|
|
+ simulationData.put("temperature_c", 20 + new Random().nextDouble() * 30);
|
|
|
+ simulationData.put("current_residual", new Random().nextDouble() * 1); // 剩余电流:0~1A
|
|
|
+ break;
|
|
|
+ // 电能采集
|
|
|
+ case 705:
|
|
|
+ // 电能:模拟正数
|
|
|
+ simulationData.put("electrical_energy", new Random().nextDouble() * 10000);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ simulationList.add(simulationData);
|
|
|
+ }
|
|
|
+
|
|
|
+ System.out.println("生成模拟数据,设备类型:" + deviceType + ",数量:" + simulationList.size());
|
|
|
+ return simulationList;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|