处理物联网模块数据入库
parent
4e39e6a5a4
commit
ea8b0b473d
|
@ -0,0 +1,249 @@
|
||||||
|
package com.zcloud.controller;
|
||||||
|
|
||||||
|
import com.xxl.job.core.context.XxlJobHelper;
|
||||||
|
import com.zcloud.entity.PageData;
|
||||||
|
import com.zcloud.mapper.datasource.tbIron.TbIronPlcMapper;
|
||||||
|
import com.zcloud.mapper.dsno2.target.MesDeviceMonitoringMapper;
|
||||||
|
import com.zcloud.util.DateUtil;
|
||||||
|
import com.zcloud.util.R;
|
||||||
|
import com.zcloud.util.Tools;
|
||||||
|
import com.zcloud.util.UuidUtil;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.tools.Tool;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("app")
|
||||||
|
public class AppPosiDeviceController {
|
||||||
|
@Resource
|
||||||
|
private TbIronPlcMapper tbIronPlcMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private MesDeviceMonitoringMapper mesDeviceMonitoringMapper;
|
||||||
|
|
||||||
|
@PostMapping("/test1")
|
||||||
|
public R test1(@RequestBody HashMap<String, String> parma) throws Exception {
|
||||||
|
System.out.println("———————————————————————————————————————————————————————————————————————————————————————————————————————————");
|
||||||
|
// 1. 初始化分组Map,确保键唯一(使用LinkedHashMap保持插入顺序,可选)
|
||||||
|
Map<String, List<Map.Entry<String, String>>> groupMap = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
for (Map.Entry<String, String> entry : parma.entrySet()) {
|
||||||
|
String key = entry.getKey();
|
||||||
|
// 提取前缀(统一处理为trimmed字符串,避免隐式空格导致的重复)
|
||||||
|
String[] keyParts = splitKeyIntoPrefixAndNumber(key);
|
||||||
|
String prefix = keyParts[0].trim(); // 去除可能的空格,确保键唯一
|
||||||
|
|
||||||
|
// 强制使用唯一键:若已存在该前缀,直接添加到现有列表;否则创建新列表
|
||||||
|
groupMap.computeIfAbsent(prefix, k -> new ArrayList<>()).add(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 组内按数字排序(空数字视为0)
|
||||||
|
for (List<Map.Entry<String, String>> group : groupMap.values()) {
|
||||||
|
group.sort((e1, e2) -> {
|
||||||
|
String[] parts1 = splitKeyIntoPrefixAndNumber(e1.getKey());
|
||||||
|
String[] parts2 = splitKeyIntoPrefixAndNumber(e2.getKey());
|
||||||
|
int num1 = parseNumber(parts1[1]);
|
||||||
|
int num2 = parseNumber(parts2[1]);
|
||||||
|
return Integer.compare(num1, num2);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 打印分组(每个组只输出一次)
|
||||||
|
System.out.println("===== 传感器设备数据(去重分组输出) =====");
|
||||||
|
|
||||||
|
// 遍历分组Map(已去重,每个组只输出一次)
|
||||||
|
groupMap.forEach((prefix, sortedGroup) -> {
|
||||||
|
StringBuilder groupContent = new StringBuilder();
|
||||||
|
for (Map.Entry<String, String> entry : sortedGroup) {
|
||||||
|
groupContent.append(entry.getKey()).append(": ").append(entry.getValue()).append(",");
|
||||||
|
}
|
||||||
|
// 移除末尾多余的逗号
|
||||||
|
if (groupContent.length() > 0) {
|
||||||
|
groupContent.setLength(groupContent.length() - 1);
|
||||||
|
}
|
||||||
|
// 输出分组
|
||||||
|
System.out.println("【" + prefix + "组】:" + groupContent);
|
||||||
|
});
|
||||||
|
System.out.println("———————————————————————————————————————————————————————————————————————————————————————————————————————————");
|
||||||
|
return R.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析数字部分(空或非数字均视为0)
|
||||||
|
*/
|
||||||
|
private int parseNumber(String numberPart) {
|
||||||
|
if (numberPart == null || numberPart.trim().isEmpty()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return Integer.parseInt(numberPart.trim());
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拆分键为前缀和数字部分(扩展匹配 z2zt、t2td、T2td、td,确保不同前缀正确分组)
|
||||||
|
*/
|
||||||
|
private String[] splitKeyIntoPrefixAndNumber(String key) {
|
||||||
|
if (key == null) {
|
||||||
|
return new String[]{"", null};
|
||||||
|
}
|
||||||
|
String trimmedKey = key.trim(); // 去除首尾空格,避免干扰
|
||||||
|
|
||||||
|
// 优先匹配 T2zt 前缀
|
||||||
|
if (trimmedKey.startsWith("T2zt")) {
|
||||||
|
String numberPart = trimmedKey.substring(4); // 截取 z2zt 后的内容作为数字部分
|
||||||
|
return new String[]{"T2zt", numberPart};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 匹配 t2zt 前缀
|
||||||
|
if (trimmedKey.startsWith("t2zt")) {
|
||||||
|
String numberPart = trimmedKey.substring(4); // 截取 z2zt 后的内容作为数字部分
|
||||||
|
return new String[]{"t2zt", numberPart};
|
||||||
|
}
|
||||||
|
// 匹配 t2td 前缀
|
||||||
|
else if (trimmedKey.startsWith("t2td")) {
|
||||||
|
String numberPart = trimmedKey.substring(4); // 截取 t2td 后的内容作为数字部分
|
||||||
|
return new String[]{"t2td", numberPart};
|
||||||
|
}
|
||||||
|
// 匹配 T2td 前缀(原逻辑保留)
|
||||||
|
else if (trimmedKey.startsWith("T2td")) {
|
||||||
|
String numberPart = trimmedKey.substring(4); // 截取 T2td 后的内容作为数字部分
|
||||||
|
return new String[]{"T2td", numberPart};
|
||||||
|
}
|
||||||
|
// 匹配 td 前缀(原逻辑保留)
|
||||||
|
else if (trimmedKey.startsWith("td")) {
|
||||||
|
String numberPart = trimmedKey.substring(2); // 截取 td 后的内容作为数字部分
|
||||||
|
return new String[]{"td", numberPart};
|
||||||
|
}
|
||||||
|
// 其他键:前缀为自身,无数字部分
|
||||||
|
else {
|
||||||
|
return new String[]{trimmedKey, null};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/receiver")
|
||||||
|
public R receiver(@RequestBody HashMap<String, String> parma) throws Exception {
|
||||||
|
System.out.println("parma数据:" +parma);
|
||||||
|
// 定义处理批次数据 ID
|
||||||
|
String processingBatchId = UuidUtil.get32UUID();
|
||||||
|
// 批处理时间
|
||||||
|
String processingTime = DateUtil.date2Str(new Date());
|
||||||
|
// td1 和 t2td1 的值是一氧化碳浓度 每次数据至多两条(安装在一起的设备)
|
||||||
|
String location = parma.get("location");
|
||||||
|
// 根据设备的地点和td1或者是t2td1判断出设备对应系统中的哪个
|
||||||
|
// 查出所有一氧化碳设备的阈值配置
|
||||||
|
PageData equPd = new PageData();
|
||||||
|
List<PageData> targetAllList = tbIronPlcMapper.listTargetByEquId(equPd);
|
||||||
|
// 定义一个存储集合用于存储要入库的数据
|
||||||
|
List<Map<String, Object>> dataList = new ArrayList<>();
|
||||||
|
if (location.equals("1#高炉中控室")) {
|
||||||
|
// 如果是1#高炉中控室,td1的值为1#高炉中控室(上)的CO浓度,t2td1的值为1#高炉中控室(下)的CO浓度。
|
||||||
|
if (parma.containsKey("td1")) {
|
||||||
|
// 如果包含td1,证明1#高炉中控室(上)的CO浓度有值 将一氧化碳的浓度值、所属设备编码(EQUIPMENT_ID)、预警阈值传入方法
|
||||||
|
dataList.add(saveData(parma.get("td1"), "8eab7aff5585192b028e9592e2a6c6e9", targetAllList, processingBatchId, processingTime));
|
||||||
|
} else if (parma.containsKey("t2td1")) {
|
||||||
|
dataList.add(saveData(parma.get("t2td1"), "cf0c414e21e0413aac3ac53e53c33058", targetAllList, processingBatchId, processingTime));
|
||||||
|
}
|
||||||
|
} else if (location.equals("2#高炉控制室")) {
|
||||||
|
System.out.println("2#高炉控制室");
|
||||||
|
} else if (location.equals("3#高炉控制室")) {
|
||||||
|
System.out.println("3#高炉控制室");
|
||||||
|
} else if (location.equals("型钢加热炉")) {
|
||||||
|
System.out.println("型钢加热炉");
|
||||||
|
} else if (location.equals("15万高炉煤气柜")) {
|
||||||
|
System.out.println("15万高炉煤气柜");
|
||||||
|
}
|
||||||
|
// 存储集合中处理好的数据
|
||||||
|
mesDeviceMonitoringMapper.saveBatchFromMes(dataList);
|
||||||
|
XxlJobHelper.log("成功保存{}条物联网模块数据到本地数据库", dataList.size());
|
||||||
|
return R.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 定义一个通用的保存数据的方法
|
||||||
|
HashMap<String, Object> saveData(String CURRENT_VALUE, String EQUIPMENT_ID, List<PageData> targetAllList, String processingBatchId, String processingTime) {
|
||||||
|
// 根据给出的设备ID,找出对应设备的预警阈值数据
|
||||||
|
List<PageData> collect = targetAllList.stream().filter(item -> !Tools.isEmpty(item.get("EQUIPMENT_ID")) && item.get("EQUIPMENT_ID").equals(EQUIPMENT_ID)).collect(Collectors.toList());
|
||||||
|
// 定义数据Map
|
||||||
|
HashMap<String, Object> data = new HashMap<>();
|
||||||
|
data.put("MONITORING_ID", UuidUtil.get32UUID());
|
||||||
|
data.put("CURRENT_VALUE", CURRENT_VALUE);
|
||||||
|
data.put("PROCESSING_TIME", processingBatchId);
|
||||||
|
data.put("PROCESSING_BATCH_ID", processingTime);
|
||||||
|
data.put("INSERT_TIME", DateUtil.date2Str(new Date()));
|
||||||
|
data.put("WARNING", 0); // 是否告警 要完善相关告警逻辑进行判断
|
||||||
|
data.put("GATHER_TIME", 5);
|
||||||
|
data.put("PLC_NAME", "");
|
||||||
|
data.put("OVERVIEW_OF_ALERTS", "");
|
||||||
|
// 每个设备只有一个监测数据阈值,也就是一氧化碳浓度
|
||||||
|
if (collect.size() > 0) {
|
||||||
|
PageData pageData = collect.get(0);
|
||||||
|
data.put("TARGET_NAME", pageData.getString("TARGET_NAME"));
|
||||||
|
data.put("IPCDEVICE_ID", pageData.getString("IPCDEVICE_ID"));
|
||||||
|
data.put("PLC_ID", pageData.getString("PLC_ID"));
|
||||||
|
data.put("TARGET_TYPE", pageData.getString("TARGET_TYPE"));
|
||||||
|
data.put("TARGET_PLACE", pageData.getString("TARGET_PLACE"));
|
||||||
|
data.put("TARGET_UNIT", pageData.getString("TARGET_UNIT"));
|
||||||
|
data.put("THRESHOLD_UP_LIMIT", pageData.getString("THRESHOLD_UP_LIMIT"));
|
||||||
|
data.put("THRESHOLD_UP_UP_LIMIT", pageData.getString("THRESHOLD_UP_UP_LIMIT"));
|
||||||
|
data.put("THRESHOLD_DOWN_LIMIT", pageData.getString("THRESHOLD_DOWN_LIMIT"));
|
||||||
|
data.put("THRESHOLD_DOWN_DOWN_LIMIT", pageData.getString("THRESHOLD_DOWN_DOWN_LIMIT"));
|
||||||
|
data.put("RANGE_UP", pageData.getString("RANGE_UP"));
|
||||||
|
data.put("RANGE_DOWN", pageData.getString("RANGE_DOWN"));
|
||||||
|
data.put("TARGET_DESCRIPTION", pageData.getString("TARGET_DESCRIPTION"));
|
||||||
|
data.put("BIT_NO", pageData.getString("BIT_NO"));
|
||||||
|
data.put("SIGNAL_TYPE", pageData.getString("SIGNAL_TYPE"));
|
||||||
|
data.put("ALARM_VALUE", pageData.getString("ALARM_VALUE"));
|
||||||
|
data.put("TARGET_STATUS", pageData.getString("TARGET_STATUS"));
|
||||||
|
data.put("CORPINFO_ID", pageData.getString("CORPINFO_ID"));
|
||||||
|
} else {
|
||||||
|
data.put("IPCDEVICE_ID", "");
|
||||||
|
data.put("PLC_ID", "");
|
||||||
|
data.put("TARGET_TYPE", "");
|
||||||
|
data.put("TARGET_PLACE", "");
|
||||||
|
data.put("TARGET_UNIT", "");
|
||||||
|
data.put("THRESHOLD_UP_LIMIT", "");
|
||||||
|
data.put("THRESHOLD_UP_UP_LIMIT", "");
|
||||||
|
data.put("THRESHOLD_DOWN_LIMIT", "");
|
||||||
|
data.put("THRESHOLD_DOWN_DOWN_LIMIT", "");
|
||||||
|
data.put("RANGE_UP", "");
|
||||||
|
data.put("RANGE_DOWN", "");
|
||||||
|
data.put("TARGET_DESCRIPTION", "");
|
||||||
|
data.put("BIT_NO", "");
|
||||||
|
data.put("SIGNAL_TYPE", "");
|
||||||
|
data.put("ALARM_VALUE", "");
|
||||||
|
data.put("TARGET_STATUS", "");
|
||||||
|
data.put("CORPINFO_ID", "");
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
// 参数示例
|
||||||
|
// {
|
||||||
|
// "td1": "node0101", -》设备的CO浓度
|
||||||
|
// "workshop": "高炉区域", -》车间
|
||||||
|
// "equipment": "气体检测报警控制器", -》设备名称
|
||||||
|
// "mode!": "ZD-Y32", -》
|
||||||
|
// "vendor": "南京智达", -》设备厂家
|
||||||
|
// "location": "1#高炉中控室", -》安装地点
|
||||||
|
// "display area": "1#高炉中控室", -》安装地点
|
||||||
|
// "host id": "T001", -》
|
||||||
|
|
||||||
|
// "t2td1": "node0201", -》设备的CO浓度
|
||||||
|
// "t2zt1": "node0209", -》设备的状态 (不用管)
|
||||||
|
// "workshop": "高炉区域", -》车间
|
||||||
|
// "equipment": "CO报警仪", -》设备名称
|
||||||
|
// "mode!": "CL-9100", -》
|
||||||
|
// "vendor": "深圳市科陆", -》设备厂家
|
||||||
|
// "location": "1#高炉中控室", -》安装地点
|
||||||
|
// "display area": "1#高炉中控室", -》安装地点
|
||||||
|
// "host id": "T001-T002" -》
|
||||||
|
// }
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
|
||||||
|
|
||||||
|
package com.zcloud.util;
|
||||||
|
|
||||||
|
import org.apache.http.HttpStatus;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回数据
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class R extends HashMap<String, Object> {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public R() {
|
||||||
|
put("code", 200);
|
||||||
|
put("result", "success");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static R error() {
|
||||||
|
return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常,请联系管理员");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static R error(String msg) {
|
||||||
|
return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static R error(int code, String msg) {
|
||||||
|
R r = new R();
|
||||||
|
r.put("code", code);
|
||||||
|
r.put("result", "failed");
|
||||||
|
r.put("msg", msg);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static R ok(String msg) {
|
||||||
|
R r = new R();
|
||||||
|
r.put("msg", msg);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static R ok(Map<String, Object> map) {
|
||||||
|
R r = new R();
|
||||||
|
r.putAll(map);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static R ok() {
|
||||||
|
return new R();
|
||||||
|
}
|
||||||
|
|
||||||
|
public R put(String key, Object value) {
|
||||||
|
super.put(key, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue