Commit 98ce8780053dd1e527ce380ddf2ad2baf878de20

Authored by 胡翰林
1 parent 2af32686

潘集

中建材设备上报
... ... @@ -20,6 +20,8 @@ public class HealthController {
20 20 private ShzzDevicePullService shzzDevicePullService;
21 21 @Resource
22 22 private HnHsqDeviceReportService hnHsqDeviceReportService;
  23 + @Resource
  24 + private PjDeviceReportService pjDeviceReportService;
23 25
24 26 @GetMapping("/health")
25 27 public String health() {
... ... @@ -45,4 +47,8 @@ public class HealthController {
45 47 shzzDevicePullService.pullDeviceAndPushToIot();
46 48 }
47 49
  50 + @GetMapping("/test")
  51 + public void test() {
  52 + pjDeviceReportService.reportZongJianCaiEnergy();
  53 + }
48 54 }
... ...
... ... @@ -80,8 +80,11 @@ public class PjDeviceReportService {
80 80 @Value("${pj.third.energyFormId:t6937bc62e4332f00072a0849}")
81 81 private String energyFormId;
82 82
83   - @Value("${pj.third.selectEnergySql:SELECT * FROM ts_kv_dictionary;}")
84   - private String selectEnergySql;
  83 + @Value("${pj.third.selectJinHongEnergySql:SELECT * FROM ts_kv_dictionary;}")
  84 + private String selectJinHongEnergySql;
  85 +
  86 + @Value("${pj.third.selectZongJianCaiEnergySql:SELECT * FROM ts_kv_dictionary;}")
  87 + private String selectZongJianCaiEnergySql;
85 88
86 89 @Resource
87 90 private RedisTemplate<String, String> redisTemplate;
... ... @@ -250,16 +253,16 @@ public class PjDeviceReportService {
250 253 }
251 254
252 255 /**
253   - * 企业设备能耗上报
  256 + * 金宏能耗上报
254 257 */
255   - public void batchReportEnergyEnterprise() {
  258 + public void reportJinHongEnergy() {
256 259 log.info("开始执行企业设备能耗上报任务");
257 260 long startTime = System.currentTimeMillis();
258 261
259 262 try {
260 263 // 1. 查询需要同步的数据
261 264 log.info("步骤1: 开始查询需要同步的设备数据");
262   - List<Object> needSyncDataList = initConnectAndSelectData2();
  265 + List<Object> needSyncDataList = initJinHongConnectAndSelectData();
263 266
264 267 if (CollectionUtils.isEmpty(needSyncDataList)) {
265 268 log.info("未查询到需要同步的设备数据,任务结束");
... ... @@ -416,6 +419,162 @@ public class PjDeviceReportService {
416 419 }
417 420 }
418 421
  422 + /**
  423 + * 金宏能耗上报
  424 + */
  425 + public void reportZongJianCaiEnergy() {
  426 + log.info("开始执行企业设备能耗上报任务");
  427 + long startTime = System.currentTimeMillis();
  428 +
  429 + try {
  430 + // 1. 查询需要同步的数据
  431 + log.info("步骤1: 开始查询需要同步的设备数据");
  432 + List<Object> needSyncDataList = initZongJianCaiConnectAndSelectData();
  433 +
  434 + if (CollectionUtils.isEmpty(needSyncDataList)) {
  435 + log.info("未查询到需要同步的设备数据,任务结束");
  436 + return;
  437 + }
  438 +
  439 + log.info("共查询到 {} 条设备数据需要同步", needSyncDataList.size());
  440 +
  441 + // 2. 准备上报数据
  442 + log.info("步骤2: 开始准备上报数据");
  443 +
  444 + CloseableHttpClient httpclient = HttpClients.createDefault();
  445 + HttpPost httpPost = new HttpPost(reportUrl);
  446 +
  447 + // 3. 获取并设置Token
  448 + log.info("步骤3: 获取访问令牌");
  449 + String token = getTokenNoCache();
  450 + if (StringUtils.isBlank(token)) {
  451 + log.error("获取访问令牌失败,无法进行数据上报");
  452 + return;
  453 + }
  454 +
  455 + httpPost.setHeader("Authorization", "Bearer " + token);
  456 + httpPost.setHeader("Content-Type", "application/json; charset=utf-8");
  457 + log.info("请求URL: {}, Token已设置", reportUrl);
  458 +
  459 + // 4. 构建上报数据
  460 + log.info("步骤4: 构建上报数据结构");
  461 + List<Map<String, Object>> dataList = new ArrayList<>(needSyncDataList.size());
  462 + List<Map<String, Object>> saveDataList = new ArrayList<>(needSyncDataList.size());
  463 + int successCount = 0;
  464 + int errorCount = 0;
  465 + DeviceDataStorage storage = new DeviceDataStorage();
  466 + for (int i = 0; i < needSyncDataList.size(); i++) {
  467 + try {
  468 + Object needSyncData = needSyncDataList.get(i);
  469 + List<Object> dataObject = (ArrayList) needSyncData;
  470 +
  471 + if (dataObject.size() < 4) {
  472 + log.warn("第 {} 条数据格式不正确,期望至少4个字段,实际: {}", i + 1, dataObject.size());
  473 + errorCount++;
  474 + continue;
  475 + }
  476 +
  477 + Map<String, Object> data = new HashMap<>();
  478 + String deviceCode = (String) dataObject.get(2);
  479 + String energyType = (String) dataObject.get(3);
  480 +
  481 + data.put("entName", dataObject.get(0));
  482 + data.put("deviceName", dataObject.get(1));
  483 + data.put("deviceCode", deviceCode);
  484 + data.put("energyType", energyType);
  485 + Long ts = (Long) dataObject.get(5);
  486 + DeviceDataStorage.DeviceRecord lastRecord = storage.getLastRecord(deviceCode);
  487 + if (lastRecord == null) {
  488 + log.warn("第 {} 条数据,设备:{} 未找到上一期上报数据", i + 1, deviceCode);
  489 + continue;
  490 + }
  491 + if (lastRecord.getTimestamp() >= ts) {
  492 + log.warn("第 {} 条数据,设备:{} 数据未更新无需上报", i + 1, deviceCode);
  493 + continue;
  494 + }
  495 + Double energyValue = toDouble(dataObject.get(4));
  496 +
  497 + if ("电".equals(energyType) || "天然气".equals(energyType)|| "水".equals(energyType)) {
  498 + data.put("energyValue", energyValue);
  499 + data.put("timeSpan", "日");
  500 + data.put("collectTime", toYyyyMmDd(ts));
  501 + } else {
  502 + log.warn("第 {} 条数据,设备:{} 物模型数据错误!", i + 1, deviceCode);
  503 + continue;
  504 + }
  505 +
  506 + dataList.add(data);
  507 + Map<String, Object> saveData = (Map<String, Object>) SerializationUtils.clone((Serializable) data);
  508 + saveData.put("ts",ts);
  509 + saveData.put("orignValue",energyValue);
  510 + saveDataList.add(saveData);
  511 +
  512 + successCount++;
  513 +
  514 + // 每100条记录输出一次进度
  515 + if (successCount % 100 == 0) {
  516 + log.info("已成功构建 {} 条上报数据", successCount);
  517 + }
  518 +
  519 + } catch (Exception e) {
  520 + log.error("处理第 {} 条数据时发生异常", i + 1, e);
  521 + errorCount++;
  522 + }
  523 + }
  524 +
  525 + log.info("数据构建完成,成功: {} 条,失败: {} 条", successCount, errorCount);
  526 +
  527 + if (CollectionUtils.isEmpty(dataList)) {
  528 + log.error("没有成功构建任何上报数据,任务结束");
  529 + return;
  530 + }
  531 +
  532 + // 5. 构建请求体
  533 + log.info("步骤5: 构建请求体");
  534 + Map<String, Object> sendData = new HashMap<>(3);
  535 + sendData.put("formId", energyFormId);
  536 + List<String> uniqueKeyList = Arrays.asList(energyUniqueKeys.split(","));
  537 + sendData.put("uniqueKeys", uniqueKeyList);
  538 + sendData.put("datas", dataList);
  539 +
  540 + String json = JSON.toJSONString(sendData);
  541 + log.debug("请求体JSON数据: {}", json);
  542 + log.info("请求体大小: {} 字符", json.length());
  543 +
  544 + httpPost.setEntity(new StringEntity(json, StandardCharsets.UTF_8));
  545 +
  546 + // 6. 发送请求
  547 + log.info("步骤6: 发送HTTP请求到第三方平台");
  548 + try (CloseableHttpResponse response = httpclient.execute(httpPost)) {
  549 + int statusCode = response.getStatusLine().getStatusCode();
  550 + String result = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
  551 +
  552 + log.info("HTTP响应状态码: {}", statusCode);
  553 + log.info("HTTP响应内容: {}", result);
  554 +
  555 + if (statusCode == 200) {
  556 + JSONObject jsonResult = JSON.parseObject(result);
  557 + if (jsonResult != null && "true".equalsIgnoreCase(jsonResult.getString("success"))) {
  558 + log.info("数据上报成功!共上报 {} 条设备数据", dataList.size());
  559 + //记录上报数据
  560 + saveReportData(saveDataList);
  561 + } else {
  562 + log.error("数据上报失败!响应状态异常: {}", result);
  563 + }
  564 + } else {
  565 + log.error("HTTP请求失败,状态码: {}", statusCode);
  566 + }
  567 +
  568 + } catch (Exception e) {
  569 + log.error("发送HTTP请求时发生异常", e);
  570 + }
  571 +
  572 + } finally {
  573 + long endTime = System.currentTimeMillis();
  574 + log.info("企业设备能耗上报任务执行完成,总耗时: {} 毫秒", (endTime - startTime));
  575 + }
  576 + }
  577 +
419 578 private void saveReportData(List<Map<String, Object>> dataList) {
420 579 if (CollectionUtils.isEmpty(dataList)) {
421 580 return;
... ... @@ -654,7 +813,90 @@ public class PjDeviceReportService {
654 813 return resultList;
655 814 }
656 815
657   - private List<Object> initConnectAndSelectData2() {
  816 + private List<Object> initJinHongConnectAndSelectData() {
  817 + Connection connection = null;
  818 + PreparedStatement statement = null;
  819 + ResultSet resultSet = null;
  820 + HikariDataSource dataSource = null;
  821 + List<Object> resultList = new ArrayList<>();
  822 +
  823 + log.info("开始连接数据库,URL: {}", jdbcUrl);
  824 +
  825 + try {
  826 + HikariConfig config = new HikariConfig();
  827 + config.setJdbcUrl(jdbcUrl);
  828 + config.setUsername(jdbcUserName);
  829 + config.setPassword(jdbcPassword);
  830 + config.setDriverClassName("org.postgresql.Driver");
  831 + config.setMaximumPoolSize(5);
  832 + config.setMinimumIdle(5);
  833 + config.setConnectionTimeout(60000);
  834 + config.setConnectionTestQuery("SELECT 1");
  835 +
  836 + dataSource = new HikariDataSource(config);
  837 + log.info("Hikari连接池配置完成");
  838 +
  839 + connection = dataSource.getConnection();
  840 + log.info("数据库连接成功");
  841 +
  842 + statement = connection.prepareStatement(selectJinHongEnergySql);
  843 + log.info("执行SQL查询: {}", selectSql);
  844 +
  845 + resultSet = statement.executeQuery();
  846 + ResultSetMetaData metaData = resultSet.getMetaData();
  847 + int columnCount = metaData.getColumnCount();
  848 + log.info("查询结果集元数据获取成功,共{}列", columnCount);
  849 +
  850 + int rowCount = 0;
  851 + while (resultSet.next()) {
  852 + List<Object> result = new ArrayList<>(columnCount);
  853 + for (int index = 1; index <= columnCount; index++) {
  854 + int columnType = metaData.getColumnType(index);
  855 + Object value = getTypedValue(resultSet, index, columnType);
  856 + result.add(value);
  857 + }
  858 + resultList.add(result);
  859 + rowCount++;
  860 +
  861 + // 每处理1000行记录一次日志
  862 + if (rowCount % 1000 == 0) {
  863 + log.info("已处理{}行数据", rowCount);
  864 + }
  865 + }
  866 +
  867 + log.info("数据查询完成,共获取{}行数据", rowCount);
  868 +
  869 + } catch (SQLException e) {
  870 + log.error("数据库操作异常,URL: {}, 用户名: {}", jdbcUrl, jdbcUserName, e);
  871 + } catch (Exception e) {
  872 + log.error("初始化数据库连接或查询数据时发生异常", e);
  873 + } finally {
  874 + // 释放资源
  875 + try {
  876 + if (resultSet != null) resultSet.close();
  877 + if (statement != null) statement.close();
  878 + if (connection != null) connection.close();
  879 + log.info("数据库连接资源已释放");
  880 + } catch (SQLException e) {
  881 + log.error("关闭数据库资源时发生异常", e);
  882 + }
  883 +
  884 + if (dataSource != null) {
  885 + try {
  886 + dataSource.close();
  887 + log.info("HikariDataSource连接池已关闭");
  888 + } catch (Exception e) {
  889 + log.error("关闭HikariDataSource连接池时发生异常", e);
  890 + }
  891 + }
  892 + }
  893 +
  894 + log.info("数据库操作完成,返回{}条记录", resultList.size());
  895 + return resultList;
  896 + }
  897 +
  898 +
  899 + private List<Object> initZongJianCaiConnectAndSelectData() {
658 900 Connection connection = null;
659 901 PreparedStatement statement = null;
660 902 ResultSet resultSet = null;
... ... @@ -680,7 +922,7 @@ public class PjDeviceReportService {
680 922 connection = dataSource.getConnection();
681 923 log.info("数据库连接成功");
682 924
683   - statement = connection.prepareStatement(selectEnergySql);
  925 + statement = connection.prepareStatement(selectZongJianCaiEnergySql);
684 926 log.info("执行SQL查询: {}", selectSql);
685 927
686 928 resultSet = statement.executeQuery();
... ...
... ... @@ -39,7 +39,8 @@ public class PanJiZoneScheduler extends AbstractZoneScheduler {
39 39 logStart(taskName);
40 40 try {
41 41 log.info("[{}] PJ pushing devices...", getZoneName());
42   - pjDeviceReportService.batchReportEnergyEnterprise();
  42 + pjDeviceReportService.reportJinHongEnergy();
  43 + pjDeviceReportService.reportZongJianCaiEnergy();
43 44 Thread.sleep(1000);
44 45 } catch (Exception e) {
45 46 logError(taskName, e);
... ...
... ... @@ -157,7 +157,7 @@ pj:
157 157 AND de.device_profile_id = '0418b010-f01d-11f0-9cb8-e3376d1e7978';"
158 158 energyFormId: "t69393ccde4332f00072a08e8"
159 159 energyUniqueKeys: "entName,deviceCode,timeSpan,collectTime,energyType"
160   - selectEnergySql: "SELECT
  160 + selectJinHongEnergySql: "SELECT
161 161 tko.name AS entName,
162 162 de.name AS deviceName,
163 163 dc.credentials_id AS deviceCode,
... ... @@ -175,8 +175,28 @@ pj:
175 175 LEFT JOIN device_credentials dc ON de.id = dc.device_id
176 176 WHERE
177 177 de.tenant_id = '0414df80-f01d-11f0-9cb8-e3376d1e7978'
  178 + and de.organization_id='12eade61-d3aa-47d6-a71b-1d1384dc4c30'
  179 + AND de.device_profile_id IN ('b1845b90-6634-11f1-9cb8-e3376d1e7978', '8c195900-6634-11f1-9cb8-e3376d1e7978', '5eb07070-6634-11f1-9cb8-e3376d1e7978');"
  180 + selectZongJianCaiEnergySql: "SELECT
  181 + tko.name AS entName,
  182 + de.name AS deviceName,
  183 + dc.credentials_id AS deviceCode,
  184 + case tkl.key
  185 + when 544 then '电'
  186 + when 545 then '水'
  187 + when 546 then '天然气' end AS energyType,
  188 + COALESCE (tkl.dbl_v, tkl.long_v, 0) AS deviceValue,
  189 + tkl.ts
  190 + FROM
  191 + device de
  192 + LEFT JOIN tk_organization tko ON de.organization_id = tko.id
  193 + LEFT JOIN ts_kv_latest tkl ON de.id = tkl.entity_id
  194 + AND tkl.KEY IN (544, 545, 546)
  195 + LEFT JOIN device_credentials dc ON de.id = dc.device_id
  196 + WHERE
  197 + de.tenant_id = '0414df80-f01d-11f0-9cb8-e3376d1e7978'
  198 + and de.organization_id='00347cce-eb9e-4b6d-897c-ae39dbdf53c7'
178 199 AND de.device_profile_id IN ('b1845b90-6634-11f1-9cb8-e3376d1e7978', '8c195900-6634-11f1-9cb8-e3376d1e7978', '5eb07070-6634-11f1-9cb8-e3376d1e7978');"
179   -
180 200 wuwei:
181 201 third:
182 202 domain: "http://60.169.172.121:1804/report-property"
... ...