BjkjDevicePullService.java
34.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
package com.iot.scheduler.service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.iot.scheduler.model.DeviceToken;
import com.iot.scheduler.model.QxDeviceInfo;
import com.iot.scheduler.model.QxDeviceInfoDetail;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.util.UriComponentsBuilder;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
* 博晶科技(滁州)有限公司应用数据同步
*/
@Slf4j
@Service
public class BjkjDevicePullService {
@Value("${bjkj.iot.organizeId:}")
private String iotOrganizeId;
@Value("${bjkj.iot.profileId}")
private String iotProfileId;
@Value("${bjkj.iot.deviceProfileId}")
private String iotDeviceProfileId;
@Value("${bjkj.iot.userName:}")
private String iotUserName;
@Value("${bjkj.iot.password:}")
private String iotPassword;
@Value("${bjkj.iot.tokenUrl}")
private String iotTokenUrl;
@Value("${bjkj.iot.infoUrl}")
private String iotDeviceInfoUrl;
@Value("${bjkj.iot.detailUrl}")
private String iotDeviceDetailUrl;
@Value("${device.token.url}")
private String deviceTokenUrl;
@Value("${bjkj.device.token.userName}")
private String deviceUserName;
@Value("${bjkj.device.token.password}")
private String devicePassword;
@Value("${device.info.url}")
private String deviceInfoUrl;
@Value("${device.detail.url}")
private String deviceDetailUrl;
final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Resource
private RedisTemplate<String, String> redisTemplate;
/**
* 设备同步主方法
* @param useRemoteData true: 从远程接口获取设备数据; false: 使用本地设备列表
*/
public void pullDeviceAndPushToIot(boolean useRemoteData) {
List<QxDeviceInfo> qxDeviceInfos = new ArrayList<>();
List<QxDeviceInfoDetail> qxAddDeviceInfoDetails = new ArrayList<>();
Map<String, QxDeviceInfoDetail> qxDeviceInfoDetailMap = new HashMap<>();
if (useRemoteData) {
// 从远程接口获取设备数据
String deviceResult = getDeviceInfo();
if (StringUtils.isBlank(deviceResult)) {
log.error("获取远程设备信息失败");
return;
}
Map<String, Object> deviceInfos = JSON.parseObject(deviceResult, new TypeReference<>() {});
JSONArray deviceInfoList = (JSONArray) deviceInfos.get("data");
for (Object o : deviceInfoList) {
JSONObject deviceInfoJson = (JSONObject) o;
QxDeviceInfo qxDeviceInfo = new QxDeviceInfo();
qxDeviceInfo.setDeviceType("DIRECT_CONNECTION");
qxDeviceInfo.setTransportType("DEFAULT");
qxDeviceInfo.setOrganizationId(iotOrganizeId);
qxDeviceInfo.setDeviceProfileId(iotDeviceProfileId);
qxDeviceInfo.setProfileId(iotProfileId);
qxDeviceInfo.setLabel("生产设备");
//设备名称
String deviceName = deviceInfoJson.getString("deviceName");
qxDeviceInfo.setName(deviceName);
qxDeviceInfo.setBrand(deviceName);
//序列号
String dtuSn = deviceInfoJson.getString("dtuSn");
qxDeviceInfo.setSn(dtuSn);
DeviceToken deviceToken = new DeviceToken();
deviceToken.setCredentialsType("ACCESS_TOKEN");
deviceToken.setCredentialsId(dtuSn);
deviceToken.setCredentialsValue(dtuSn);
qxDeviceInfo.setDeviceToken(deviceToken);
qxDeviceInfos.add(qxDeviceInfo);
//有序列号直接获取灯信息
if (StringUtils.isNotBlank(dtuSn)) {
String deviceInfoDetails = getDeviceInfoDetail(dtuSn);
if (StringUtils.isBlank(deviceInfoDetails)) {
continue;
}
Map<String, Object> deviceInfoDetailMap = JSON.parseObject(deviceInfoDetails, new TypeReference<>() {});
JSONArray deviceInfoDetailList = (JSONArray) deviceInfoDetailMap.get("data");
if (CollectionUtils.isEmpty(deviceInfoDetailList)) {
continue;
}
JSONObject deviceInfoDetailJson = (JSONObject) deviceInfoDetailList.get(0);
//灯详情数据
//序列号
String dtuSnDetail = deviceInfoDetailJson.getString("dtuSn");
//开始时间
String startTime = deviceInfoDetailJson.getString("startTime");
QxDeviceInfoDetail qxDeviceInfoDetail = new QxDeviceInfoDetail();
qxDeviceInfoDetail.setAlarm(0);
//灯状态(0:灭灯,1:红,2:黄,3:绿,4:蓝)
Integer lampState = deviceInfoDetailJson.getInteger("lampState");
switch (lampState) {
case 0:
qxDeviceInfoDetail.setStatus("OFF");
break;
case 1:
qxDeviceInfoDetail.setStatus("ERROR");
qxDeviceInfoDetail.setAlarm(1);
break;
case 2:
qxDeviceInfoDetail.setStatus("STAND");
break;
case 3:
qxDeviceInfoDetail.setStatus("RUN");
break;
default:
continue;
}
if (StringUtils.isNotBlank(startTime)) {
try {
qxDeviceInfoDetail.setStartTime(dateFormat.parse(startTime));
} catch (Exception e) {
log.error("时间格式出错");
qxDeviceInfoDetail.setStartTime(new Date());
}
} else {
qxDeviceInfoDetail.setStartTime(new Date());
}
qxDeviceInfoDetail.setDtuSn(dtuSn);
qxDeviceInfoDetailMap.put(dtuSn, qxDeviceInfoDetail);
qxAddDeviceInfoDetails.add(qxDeviceInfoDetail);
}
}
} else {
// 使用本地设备列表
List<String> deviceNameList = getDeviceNameList();
int totalDevices = deviceNameList.size();
// 按照 8:1:1 的比例分配状态
int runCount = (int) Math.round(totalDevices * 0.8);
int standCount = (int) Math.round(totalDevices * 0.1);
int offCount = totalDevices - runCount - standCount;
// 创建状态列表
List<String> statusList = new ArrayList<>();
for (int i = 0; i < runCount; i++) {
statusList.add("RUN");
}
for (int i = 0; i < standCount; i++) {
statusList.add("STAND");
}
for (int i = 0; i < offCount; i++) {
statusList.add("OFF");
}
// 打乱状态顺序,使设备状态随机分布
Collections.shuffle(statusList);
// 获取当前日期作为序列号前缀
String datePrefix = "BJKJ20260401";
for (int i = 0; i < totalDevices; i++) {
String deviceName = deviceNameList.get(i);
String status = statusList.get(i);
// 生成序列号:BJKJ20260401 + 三位数序列号(从001开始)
String serialNumber = datePrefix + String.format("%03d", (i + 1));
QxDeviceInfo qxDeviceInfo = new QxDeviceInfo();
qxDeviceInfo.setDeviceType("DIRECT_CONNECTION");
qxDeviceInfo.setTransportType("DEFAULT");
qxDeviceInfo.setOrganizationId(iotOrganizeId);
qxDeviceInfo.setDeviceProfileId(iotDeviceProfileId);
qxDeviceInfo.setProfileId(iotProfileId);
qxDeviceInfo.setLabel("生产设备");
qxDeviceInfo.setName(deviceName);
qxDeviceInfo.setBrand(deviceName);
qxDeviceInfo.setSn(serialNumber);
DeviceToken deviceToken = new DeviceToken();
deviceToken.setCredentialsType("ACCESS_TOKEN");
deviceToken.setCredentialsId(serialNumber);
deviceToken.setCredentialsValue(serialNumber);
qxDeviceInfo.setDeviceToken(deviceToken);
qxDeviceInfos.add(qxDeviceInfo);
// 创建设备详情(遥测数据)
QxDeviceInfoDetail qxDeviceInfoDetail = new QxDeviceInfoDetail();
qxDeviceInfoDetail.setAlarm(0);
qxDeviceInfoDetail.setStatus(status);
qxDeviceInfoDetail.setStartTime(new Date());
qxDeviceInfoDetail.setDtuSn(serialNumber);
qxDeviceInfoDetailMap.put(serialNumber, qxDeviceInfoDetail);
qxAddDeviceInfoDetails.add(qxDeviceInfoDetail);
log.debug("生成设备 - 名称: {}, 序列号: {}, 状态: {}", deviceName, serialNumber, status);
}
log.info("设备状态分配统计 - 总数: {}, RUN: {}, STAND: {}, OFF: {}",
totalDevices, runCount, standCount, offCount);
}
// 上传数据到IoT平台
uploadToIotPlatform(qxDeviceInfos, qxAddDeviceInfoDetails);
}
/**
* 获取IoT平台Token并上传设备数据
*/
private void uploadToIotPlatform(List<QxDeviceInfo> qxDeviceInfos, List<QxDeviceInfoDetail> qxAddDeviceInfoDetails) {
// 获取IoT平台Token
Map<String, String> qxParam = new HashMap<>(2);
qxParam.put("username", iotUserName);
qxParam.put("password", iotPassword);
HttpPost qxHttpPost = new HttpPost(iotTokenUrl);
String qxResult = sendPost(qxHttpPost, JSON.toJSONString(qxParam));
if (StringUtils.isBlank(qxResult)) {
log.error("获取IoT平台Token失败");
return;
}
Map<String, Object> qxRes = JSON.parseObject(qxResult, new TypeReference<Map<String, Object>>() {});
String qxAccessToken = (String) qxRes.get("token");
if (StringUtils.isBlank(qxAccessToken)) {
log.error("IoT平台Token为空");
return;
}
BasicHeader qxAuthorization = new BasicHeader("X-Authorization", "Bearer " + qxAccessToken);
// 批量上传设备信息
if (!CollectionUtils.isEmpty(qxDeviceInfos)) {
HttpPost qxDeviceInfoPost = new HttpPost(iotDeviceInfoUrl);
qxDeviceInfoPost.addHeader(qxAuthorization);
int successCount = 0;
int failCount = 0;
for (QxDeviceInfo qxDeviceInfo : qxDeviceInfos) {
try {
String syncDeviceInfo = sendPost(qxDeviceInfoPost, JSON.toJSONString(qxDeviceInfo));
if (StringUtils.isNotBlank(syncDeviceInfo)) {
Map<String, Object> result = JSON.parseObject(syncDeviceInfo, new TypeReference<Map<String, Object>>() {});
if (result.containsKey("id") || (result.containsKey("success") && (Boolean) result.get("success"))) {
successCount++;
log.info("设备上传成功 - 名称: {}, 序列号: {}", qxDeviceInfo.getName(), qxDeviceInfo.getSn());
} else {
failCount++;
log.error("设备上传失败 - 名称: {}, 序列号: {}, 返回: {}",
qxDeviceInfo.getName(), qxDeviceInfo.getSn(), syncDeviceInfo);
}
} else {
failCount++;
log.error("设备上传返回为空 - 名称: {}, 序列号: {}", qxDeviceInfo.getName(), qxDeviceInfo.getSn());
}
} catch (Exception e) {
failCount++;
log.error("设备上传异常 - 名称: {}, 序列号: {}", qxDeviceInfo.getName(), qxDeviceInfo.getSn(), e);
}
}
log.info("设备上传完成 - 成功: {}, 失败: {}", successCount, failCount);
}
// 批量上传设备详情(遥测数据)
if (!CollectionUtils.isEmpty(qxAddDeviceInfoDetails)) {
int successCount = 0;
int failCount = 0;
for (QxDeviceInfoDetail qxDeviceInfoDetail : qxAddDeviceInfoDetails) {
try {
String qxDeviceInfoDetailUrlStr = iotDeviceDetailUrl + qxDeviceInfoDetail.getDtuSn() + "/telemetry";
HttpPost qxDeviceInfoDetailPost = new HttpPost(qxDeviceInfoDetailUrlStr);
qxDeviceInfoDetailPost.addHeader(qxAuthorization);
String syncDeviceInfoDetail = sendPost(qxDeviceInfoDetailPost, JSON.toJSONString(qxDeviceInfoDetail));
successCount++;
log.debug("设备详情上传成功 - 序列号: {}, 状态: {}",
qxDeviceInfoDetail.getDtuSn(), qxDeviceInfoDetail.getStatus());
} catch (Exception e) {
failCount++;
log.error("设备详情上传异常 - 序列号: {}", qxDeviceInfoDetail.getDtuSn(), e);
}
}
log.info("设备详情上传完成 - 成功: {}, 失败: {}", successCount, failCount);
}
}
/**
* 获取设备名称列表
*/
private List<String> getDeviceNameList() {
return Arrays.asList(
"组装机_1106100002",
"组装机撕膜检改造_1106100003",
"自动标签打印机_2213140002",
"喷码机_1111190002",
"喷码机皮带线_1301110005",
"喷码滚轮线_1301100002",
"FI检查流水线(6M)_1301110003",
"流水线(9M)_1301110001",
"自动Tape贴附机_1110180001",
"客户码及易撕贴贴附机_2213140003",
"真空打包机_1401110002",
"AG膜贴膜机_1110170001",
"贴合线AG贴膜机装机_1110170002",
"贴合线AG贴膜机装机_1110170003",
"脱泡机_1110170004",
"OCR贴合机_1110160001",
"橱窗式老化炉_1202040001",
"出货膜贴膜机_1110170002",
"抽屉式老化炉_1202040004",
"抽屉式老化炉_1202040005",
"凌云AOI_1201020002",
"点灯机_1202070001",
"点灯机_1202070002",
"点灯机_1202070003",
"点灯机_1202070004",
"点灯机_1202070005",
"点灯机_1202070006",
"点灯机_1202070007",
"点灯机_1202070008",
"点灯机_1202070009",
"5点亮度治具_1202080001",
"OTP治具_1202080004",
"OTP治具_1202080005",
"OTP治具_1202080006",
"OTP治具_1202080007",
"半自动OCA软对硬贴合机_1110150001",
"半自动OCA硬对硬贴合机_1110150002",
"半自动脱泡机_1107110002",
"2.5次元_1203010002",
"膜厚测量仪_1203020001",
"水滴角测试仪_1203030001",
"条码打印机/型号:斑马105SL 分_2213150001",
"条码打印机/型号:斑马105SL 分_2213150003",
"日置数字照度计_1203040001",
"无尘室专用吸尘器_1401200001",
"能量计/UV_1203050001",
"测温仪/日本图技_1203060001",
"锥入度仪_1203070001",
"缠膜机_1401180001",
"玻璃二位蚀刻码扫码治具_2211130001",
"防爆柜_1401100001",
"重锤式表面电阻测试仪_1203080001",
"手持式热熔打包机_1401190001",
"手持式热熔打包机_1401190002",
"三坐标_1203090001",
"背光点胶组装机_1106100004",
"双联屏AOI_1201020004",
"显微镜_1203100001",
"烤箱_1202040006",
"上板机_1301010001",
"镭雕机_1101030001",
"0.8m接驳台_1301030001",
"印刷机_1102040001",
"印刷机_1102040002",
"0.5m接驳台_1301030002",
"0.5m接驳台_1301030003",
"移载机_1301080001",
"0.5m双轨接驳台_1301030004",
"SPI_1201010001",
"1.2m双规筛选接驳台_1301030005",
"1.2m双规接驳台_1301030006",
"贴片机_1101010001",
"贴片机_1101010002",
"贴片机_1101010003",
"贴片机_1101010004",
"0.5m双轨接驳台_1301030007",
"0.5m移载机_1301080002",
"1m接驳台_1301030008",
"转角机_1301030001",
"0.5m接驳台_1301030009",
"0.85m单轨伸缩过道_1301070001",
"0.85m单轨伸缩过道_1301070002",
"0.5m接驳台_1301030010",
"转角机_1301030002",
"0.5m接驳台_1301030011",
"0.5m移载机_130108003",
"0.5m双轨接驳台_1301030012",
"回流焊_1103050001",
"0.5m双轨接驳台_1301030013",
"0.5m移载机_1301080004",
"0.5m双轨接驳台_1301030014",
"双轨储板机_1301050001",
"0.5m双轨接驳台_1301030015",
"AOI_1201030001",
"0.5m双轨接驳台_1301030016",
"0.5m移载机_1301080005",
"0.5m接驳台_1301030017",
"0.8m单轨筛选接驳台_1301030018",
"0.5m接驳台_1301030019",
"转角机_1301030003",
"0.7m接驳台_1301030020",
"0.85m单轨伸缩过道_1301070003",
"翻板机_1301040001",
"0.7m接驳台_1301030021",
"转角机_1301030004",
"1m接驳台_1301030022",
"0.8米接驳台_1301030023",
"1.2米接驳台_1301030024",
"选择焊_1103050002",
"0.8m接驳台_1301030025",
"ICT测试_1202050001",
"0.8m接驳台_1301030026",
"双轨储板机_1301050002",
"0.8m接驳台_1301030027",
"分板机_1104060001",
"MPM印刷机_1102040003",
"德律SPI_1201010002",
"德律AOI_1201030002",
"多功能贴片机_1101010005",
"回流焊_1103050002",
"德律AOI_1201030003",
"离线分板机_1104060002",
"离线镭雕机_1101030002",
"离线ICT测试_1202050002",
"冲压机_1104060003",
"叠板上板机_1301010002",
"1米接驳台_1301030028",
"1米接驳台_1301030029",
"1米接驳台_1301030030",
"1米接驳台_1301030031",
"1米接驳台_1301030032",
"储板机(冷却)_1301050003",
"PCBA烧录屏蔽罩安装_1202080001",
"扬声器安装_1106100001",
"PCBA安装/FPC检测_1202060002",
"中控PCBA第三次烧录&后壳安装_1202060003",
"卡爪固定_1105070002",
"总成AOI EOL测试_1202060001",
"支架/散热硅胶安装_1105070001",
"后壳固定_1105090001",
"提升机_1301090001",
"Plasma清洁_1109140001",
"点胶_1111170001",
"TLCM与支架贴合_1110150003",
"后壳组装_1105090002",
"提升机_1301090002",
"UWB测试夹具_1101030002",
"UWB测试夹具_1101030003",
"UWB测试夹具_1101030004",
"UWB测试夹具_1101030005",
"UWB测试夹具_1101030006",
"HY11测试夹具_1111100001",
"HY11测试夹具_1111100002",
"离线ICT_1202050003",
"离线烧录_1111170001",
"离线3D X-Ray_1202090001",
"脱泡机_1107110003",
"半自动OCA贴合机_1110150003",
"半自动背光点胶组装机_1106100005",
"热拆解返修_1106100006",
"清胶返修_1106100007",
"切割返修_1106100008",
"展威切割机_1104060005",
"展威切割机_1104060006",
"喷码机_1111190004",
"钢网清洗机_1401010001",
"钢网检查机_1401010002",
"干燥箱_1401010003",
"干燥箱_1401030002",
"干燥箱_1401030003",
"干燥箱_1401030004",
"点料机_1401060001",
"点料机_1401060002",
"锡膏搅拌机_1401070001",
"抽真空机_1401110001",
"电烙铁_1401140001",
"炉温测试仪_1401150001",
"应力测试仪_1202060001",
"Tray清洗机_001",
"喷淋工位_002",
"抖动1工位_003",
"抖动2工位_004",
"抖动3工位_005",
"烘干1工位_006",
"烘干2工位_007",
"烘干3工位_008",
"烘干4工位_009",
"大尺寸Tary水洗机_010",
"喷淋1工位_011",
"喷淋2工位_012",
"喷淋3工位_013",
"烘干1工位_014",
"烘干2工位_015",
"烘干3工位_016",
"烘干4工位_017",
"烘干5工位_018",
"风刀背板清洗机_024",
"水洗背板清洗机_025",
"喷淋1工位_026",
"喷淋2工位_027",
"喷淋3工位_028",
"烘干1工位_029",
"烘干2工位_030",
"烘干3工位_031",
"烘干4工位_032",
"烘干5工位_033",
"烘干6工位_034",
"胶框清洗机_039",
"超声波工位_040",
"喷淋1工位_041",
"喷淋2工位_042",
"烘干1工位_043",
"烘干2工位_044",
"烘干3工位_045",
"烘干4工位_046",
"烘干5工位_047",
"三合一小尺寸膜片清洗机_051",
"三合一大尺寸膜片清洗机_052",
"膜片单清设备_053",
"单工位AOI_054",
"离线背板贴胶机_055",
"离线LGP组装设备_056",
"胶条1工位_057",
"胶条2工位_058",
"滚压1工位_059",
"胶条3工位_060",
"滚压2工位_061",
"反射片组装工位_062",
"覆膜工位_063",
"离线胶框贴胶机_064",
"离线背板侧壁贴胶机_065",
"背板侧壁胶工位_066",
"LB导热胶工位_067",
"反射片固定胶工位_068",
"覆膜机_069",
"泡棉贴胶机_070",
"胶条1工位_071",
"胶条2工位_072",
"胶条3工位_073",
"胶条4工位_074",
"划压工位_075",
"撕膜1工位_076",
"撕膜2工位_077",
"称重工位_078",
"背板贴胶机_079",
"膜片组装机_080",
"扩散工位_081",
"增光工位_082",
"DBEF工位_083",
"防窥膜工位_084",
"覆膜机_085",
"背板贴胶机_086",
"膜片组装机_087",
"扩散工位_088",
"增光工位_089",
"DBEF工位_090",
"防窥膜工位_091",
"膜移检测工位_092",
"扣框工位_093",
"胶框保压工位_094",
"前加工设备_095",
"PCB工位_096",
"标签+小黑胶工位_097",
"翻转工位_098",
"堵孔1工位_099",
"堵孔2工位_100",
"灯条侧边胶工位_101",
"导热胶工位_102",
"反射片固定胶工位_103",
"泡棉贴胶机_104",
"胶条1工位_105",
"胶条2工位_106",
"胶条3工位_107",
"胶条4工位_108",
"划压工位_109",
"半成品组装_110",
"LB保压工位_111",
"胶条1工位_112",
"滚压1工位_113",
"胶条2工位_114",
"滚压2工位_115",
"胶条3工位_116",
"滚压3工位_117",
"胶条4工位_118",
"撕膜工位_119",
"反射片贴合工位_120",
"导光板组装工位_121",
"CCD检查+搬运工位_122",
"膜间胶1工位_123",
"扩散工位_124",
"膜间胶2工位_125",
"增光工位_126",
"膜间胶3工位_127",
"DBEF工位_128",
"膜间胶4工位_129",
"防窥膜工位_130",
"膜移检测工位_131",
"扣框工位_132",
"包边机_133",
"胶条1工位_134",
"胶条2工位_135",
"胶条3工位_136",
"胶条4工位_137",
"撕膜1工位_138",
"撕膜2工位_139",
"PET工位_140",
"覆膜机_141",
"自动AOI_142",
"AVI_143",
"半自动CCD检查设备_144",
"大尺寸CCD检查设备_145",
"喷码机_146",
"螺纹柱检查设备_147"
);
}
// 保留原方法以保持兼容性
public void pullDeviceAndPushToIot() {
pullDeviceAndPushToIot(true);
}
public void pullDeviceAndPushToIot2() {
pullDeviceAndPushToIot(false);
}
public String getDeviceInfoDetail(String dtuSn) {
String accessToken = getAccessToken();
Map<String, String> dtuSnOb = new HashMap<>(1);
dtuSnOb.put("dtuSn", dtuSn);
Map<String, String> headerMap = new HashMap<>(1);
headerMap.put("Authorization", "Bearer " + accessToken);
String deviceInfoDetail = sendRequestGet(deviceDetailUrl, dtuSnOb, headerMap);
if (StringUtils.isBlank(deviceInfoDetail)) {
return null;
}
Map<String, Object> deviceInfoDetailMap = JSON.parseObject(deviceInfoDetail,
new TypeReference<>() {
});
Integer deviceInfoDetailCode = (Integer) deviceInfoDetailMap.get("code");
if (deviceInfoDetailCode != 200) {
return null;
}
JSONArray deviceInfoDetailList = (JSONArray) deviceInfoDetailMap.get("data");
if (CollectionUtils.isEmpty(deviceInfoDetailList)) {
return null;
}
JSONObject deviceInfoDetailJson = (JSONObject) deviceInfoDetailList.get(0);
//灯详情数据
//灯状态(0:灭灯,1:红,2:黄,3:绿,4:蓝)
Integer lampState = deviceInfoDetailJson.getInteger("lampState");
if (lampState == null) {
return null;
}
return deviceInfoDetail;
}
public String getDeviceInfo() {
String accessToken = getAccessToken();
// 初始化headerMap并设置Authorization
Map<String, String> headerMap = new HashMap<>(1);
headerMap.put("Authorization", "Bearer " + accessToken);
Map<String, String> paramsMap = new HashMap<>();
paramsMap.put("groupName", "默认组织");
// 第一次请求设备信息
String deviceResult = sendRequestGet(deviceInfoUrl, paramsMap, headerMap);
// 检查设备信息是否为空
if (StringUtils.isBlank(deviceResult)) {
return null;
}
// 解析设备信息
Map<String, Object> deviceInfos = JSON.parseObject(deviceResult, new TypeReference<>() {
});
Integer deviceInfoCode = (Integer) deviceInfos.get("code");
// 如果code不为200,可能是accessToken失效,重新获取token并重试
if (deviceInfoCode != 200) {
accessToken = getAccessToken();
if (StringUtils.isEmpty(accessToken)) {
return null;
}
// 更新headerMap中的Authorization
headerMap.put("Authorization", "Bearer " + accessToken);
// 第二次请求设备信息
deviceResult = sendRequestGet(deviceInfoUrl, paramsMap, headerMap);
if (StringUtils.isBlank(deviceResult)) {
return null;
}
// 重新解析设备信息
deviceInfos = JSON.parseObject(deviceResult, new TypeReference<>() {
});
deviceInfoCode = (Integer) deviceInfos.get("code");
// 如果第二次请求仍然失败,返回错误信息
if (deviceInfoCode != 200) {
return null;
}
}
// 返回成功的设备信息
return deviceResult;
}
private String getAccessToken() {
String accessToken = "";
String redisKey = "bjkj_device_token";
if (StringUtils.isNotBlank(redisTemplate.opsForValue().get(redisKey)) && redisTemplate.getExpire(redisKey) > 0) {
return redisTemplate.opsForValue().get(redisKey);
}
Map<String, String> param = new HashMap<>(2);
param.put("username", deviceUserName);
param.put("password", devicePassword);
HttpPost httpPost = new HttpPost(deviceTokenUrl);
String result = sendPost(httpPost, JSON.toJSONString(param));
if (StringUtils.isBlank(result)) {
return accessToken;
}
Map<String, Object> res = JSON.parseObject(result, new TypeReference<>() {
});
Integer code = (Integer) res.get("code");
if (code == 200) {
JSONObject data = (JSONObject) res.get("data");
accessToken = (String) data.get("token");
redisTemplate.opsForValue().set(redisKey, accessToken, 3600, TimeUnit.SECONDS); // 一小时过期
}
return accessToken;
}
public static String sendRequestGet(String url, Map<String, String> params, Map<String, String> header) {
//实例化httpclient
CloseableHttpClient httpclient = HttpClients.createDefault();
url = builderUrl(url, params);
//请求结果
String content = "";
//实例化get方法
HttpGet httpget = new HttpGet(url);
if (!CollectionUtils.isEmpty(header)) {
for (Map.Entry<String, String> entry : header.entrySet()) {
httpget.setHeader(entry.getKey(), entry.getValue());
}
}
try (CloseableHttpResponse response = httpclient.execute(httpget)) {
//执行get方法
if (response.getStatusLine().getStatusCode() == 200) {
content = EntityUtils.toString(response.getEntity(), "UTF-8");
}
} catch (IOException e) {
log.error("sendRequest---GET Error!", e);
}
return content;
}
private static String builderUrl(String url, Map<String, String> params) {
UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl(url);
if (!CollectionUtils.isEmpty(params)) {
MultiValueMap<String, String> paramsValue = new LinkedMultiValueMap<>();
for (Map.Entry<String, String> entry : params.entrySet()) {
paramsValue.add(entry.getKey(), entry.getValue());
}
uriBuilder = uriBuilder.queryParams(paramsValue);
}
return uriBuilder.toUriString();
}
private String sendPost(HttpPost httpPost, String jsonData) {
CloseableHttpClient httpClient = HttpClients.createDefault();
StringEntity entity = new StringEntity(jsonData, ContentType.create("application/json", Consts.UTF_8));
httpPost.setEntity(entity);
String result = null;
try {
CloseableHttpResponse execute = httpClient.execute(httpPost);
HttpEntity res = execute.getEntity();
InputStream is = res.getContent();
int len;
byte[] buf = new byte[128];
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
while ((len = is.read(buf)) != -1) {
byteArrayOutputStream.write(buf, 0, len);
}
result = byteArrayOutputStream.toString();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
}