最近在做一个大屏监控,要实现从设备读取数据后,发送到MQ,然后通过webscoket推送到客户端展示。由于OPC发送MQ上的数据格式无法满足前台,要在后台转换数据格式,做一个数据“组装”的过程。因此记录下实现“组装”过程的大概思路。
案例
要实现将OPC发送的数据传递到前台,控制工位的状态显示。
下面是OPC发送到MQ的数据格式:
{
"task": {
"name": "HZ_NZP",
"createTime": "2020-06-29 10:17:55.457",
"dataType": "OPC",
"dataID": "1eb14b44-f0b5-4392-b227-04bdaef47f5c"
},
"opc": {
"nzp_jiyun": "0",
"nzp_absn010": "000213",
"nzp_absn020": "000214",
"nzp_andon010": "0",
"nzp_andon020": "0",
"nzp_f010_1": "0",
"nzp_f010_2": "0",
"nzp_f020_1": "0",
"nzp_s010": "0",
"nzp_s020": "0"
}
}
前端展示需要的数据格式:
{
absnArr: [
"- -",
"- -"
],
seqArr: [
'2',
'1'
],
opc: {
"equipSList": [
{
"value": "1"
},
{
"value": "0"
}
],
"stationSList": [
{
"value": "0"
},
{
"value": "0"
}
],
"andonSList": [
{
"value": "2"
},
{
"value": "0"
}
]
}
}
OPC | 前台 |
---|---|
_absn | absnArr |
_andon | andonSList |
_s | stationSList |
_f | equipSList |
怎么实现上述的JSON格式呢?这就是下面说到的“组装”过程,借助List、Map操作进行转换下就可以。以equipSList的转换为例,其它类似。equipSList的格式比较特殊,只有两个工位,但却有三个数据:nzp_f010_1、nzp_f010_2、nzp_f020_1,其中_f010有两个,要求_f010_1与_f010_1中任意一个值为1的情况下,就视为_f010设备的值等于1。因此有了这个信息,就开始动手吧。大致步骤如下:
- 接收MQ发送的数据
Map<String, String> map = JSONObject.parseObject(mqMessage, Map.class);
map = MapUtils.sortByKey(map, reverse);
- 转换equipList
List<DictVO> equipList= map.entrySet()
.stream()
.filter(r -> (r.getKey().indexOf("_f") != -1))
.map(e -> new DictVO(e.getKey(), e.getValue() == null? "" : e.getValue().trim()))
.collect(Collectors.toList());
- 针对每个设备的不同状态来组装值,比如f010设备的两种状态 _f010_1和_f010_2.
Map<String, String> resultMap = equipList.stream()
.collect(Collectors.groupingBy(DictVO::getLabel, Collectors.mapping(DictVO::getValue, Collectors.joining())));
// 排序
resultMap = MapUtils.sortByKey(resultMap, reverse);
// 状态合并
List<DictVO> equipStateList = resultMap.entrySet().stream()
.map(e -> new DictVO(e.getKey(), e.getValue().contains("1") ? "1" : "0"))
.collect(Collectors.toList());
map排序方法:
/**
* 根据map的key排序
*
* @param map 待排序的map
* @param isDesc 是否降序,true:降序,false:升序
* @return 排序好的map
*/
public static <K extends Comparable<? super K>, V> Map<K, V> sortByKey(Map<K, V> map, boolean isDesc) {
Map<K, V> result = Maps.newLinkedHashMap();
if (isDesc) {
map.entrySet().stream().sorted(Map.Entry.<K, V>comparingByKey().reversed())
.forEachOrdered(e -> result.put(e.getKey(), e.getValue()));
} else {
map.entrySet().stream().sorted(Map.Entry.<K, V>comparingByKey())
.forEachOrdered(e -> result.put(e.getKey(), e.getValue()));
}
return result;
}
/**
* 根据map的value排序
*
* @param map 待排序的map
* @param isDesc 是否降序,true:降序,false:升序
* @return 排序好的map
*/
public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map, boolean isDesc) {
Map<K, V> result = Maps.newLinkedHashMap();
if (isDesc) {
map.entrySet().stream().sorted(Map.Entry.<K, V>comparingByValue().reversed())
.forEach(e -> result.put(e.getKey(), e.getValue()));
} else {
map.entrySet().stream().sorted(Map.Entry.<K, V>comparingByValue())
.forEachOrdered(e -> result.put(e.getKey(), e.getValue()));
}
return result;
}
至此,equipStateList 的数据转换就结束了,其它的类似。