Compare commits

..

60 Commits

Author SHA1 Message Date
3067418132@qq.com 64c2158f12 1、主机详情内容修改 3 weeks ago
3067418132@qq.com f900c6f9da 1、首页增加冷源系统实时EER 3 weeks ago
3067418132@qq.com 441e1848ee 1、监视界面优化; 3 weeks ago
3067418132@qq.com 5b02ea1a80 1、垃圾PLC点位修改,需要改代码 2 months ago
3067418132@qq.com 4e61bac0de 1、本地环境配置 2 months ago
25604 d6f030e552 1、能耗查询、设备组查询分析增加数据条数 4 months ago
25604 12e93c9b78 1、配置修改 4 months ago
25604 3b25a9e235 1、首页热回收数据日累积值计算优化; 4 months ago
25604 1b27a0c287 1、热回收系统触摸屏mqtt数据处理; 4 months ago
25604 f81769b738 1、热回收系统触摸屏mqtt数据接收 4 months ago
25604 0288f2cffb 1、设备采集参数管理; 4 months ago
25604 e5e5cee85a 1、广合二厂热回收系统:设备热量查询接口、设备组热量查询接口 5 months ago
25604 786da07f68 1、优化netty上线,减少cpu使用率; 5 months ago
25604 0a76509188 1、首页添加缓存优化; 6 months ago
25604 a383aa7cd7 1、抄表记录bug修复 6 months ago
25604 cc1a258a4f 1、运行报表增加分页参数。 6 months ago
25604 981ddd6126 1、运行报表增加分页参数。 6 months ago
25604 577e98b7b3 1、采暖系统运行报表,excel导出,编辑; 6 months ago
25604 c9e81f4ab0 1、梅州账号项目菜单区别; 7 months ago
25604 da80ade668 1、修复蒸汽机运行报表以及水箱指令生成; 7 months ago
25604 1d132511c6 1、蒸汽机运行报表记录查询、编辑、excel记录导出; 7 months ago
25604 a4739b576f 1、采暖泵接口编写 7 months ago
25604 bf81ca52c9 1、生活水箱液位前后端对接; 7 months ago
25604 1be07e2157 1、添加液位计采集 7 months ago
25604 e0df3ad93a 1、优化首页查询sql; 8 months ago
25604 22ce82f641 1、每日抄表记录报表、热水热泵运行报表添加。 8 months ago
v-lijf43 90f667ca72 1、添加豪生酒店运营部值班电话账号 8 months ago
25604 2b9f736dbb 1、风柜优化 8 months ago
25604 bc2ab582ea 1、修复热泵采集电流设置; 8 months ago
25604 6046c172a6 1、主机运行报表优化; 8 months ago
25604 bc7087a559 1、区域管理接口对接以及优化; 8 months ago
v-lijf43 42b108d055 1、日月年统计修复; 8 months ago
v-lijf43 fe759a75f4 1、添加采集点质量逻辑字段; 8 months ago
25604 f0ecb0f048 1、优化报警记录 8 months ago
v-lijf43 3c02d03a12 1、修复报警记录生成; 8 months ago
25604 60a954bcd3 1、优化风柜系统定时列表排序; 9 months ago
25604 4d64b681a9 1、定时开关风柜逻辑优化; 9 months ago
25604 99501add71 1、定时开关风柜逻辑优化; 9 months ago
25604 3754345b3d 1、当采集记录大于10000,推出; 9 months ago
25604 f8dad021d8 1、当采集记录小于等于0,则发送到延迟队列; 10 months ago
25604 0c0cf2bdf1 1、修复设备在线定时任务; 10 months ago
25604 77124eff14 1、添加锅炉主机数据点位处理(研华网关只支持4个mqtt,目前没有使用); 10 months ago
25604 5fb572cd4d 1、修复定时报警、热水记录生成; 10 months ago
25604 3ee23dea5a 1、主机系统参数报表导出、查询、编辑、定时执行存储过程 10 months ago
25604 5167e0c702 1、延迟队列实现异常误报警; 10 months ago
25604 9b4d5faf18 1、优化报警生成;2、优化微信推送异常功能; 11 months ago
25604 d2c9fca950 1、添加了冷源电表,优化对应功能。 11 months ago
25604 065e8df394 1、优化定时器:数据分析,楼层能耗分析。 12 months ago
25604 ff709ec621 1、优化策略管理排序问题。 12 months ago
25604 4d696317f2 1、报警添加微信通知功能,增加模板。 12 months ago
25604 b8d5667431 1、报警添加微信通知功能。 12 months ago
25604 4ad037f002 1、生活热水供水系统楼层查询、项目总览、能源分析、用能查询、数据分析相关接口 12 months ago
25604 dcc9307d54 1、生活热水供水系统获取设备状态信息数据 1 year ago
25604 e457861976 1、netty控制热泵设置; 1 year ago
25604 81c8a35c76 1、netty控制热泵设置; 1 year ago
25604 6973b889c8 1、netty控制热泵设置; 1 year ago
mh 36d60e0b79 1、添加通过DTU-4G,netty方式设置热泵信息; 1 year ago
mh 1603247df1 1、添加netty采集生活热水水电表、热泵信息; 1 year ago
v-lijf43 b22ba182dc PID调节风柜系统 1 year ago
mh d268edfce2 1、风柜系统添加定时开关机逻辑处理; 1 year ago
  1. BIN
      doc/节能改造每日能耗统计表.xlsx
  2. 4
      mh-admin/src/main/java/com/mh/MHRunner.java
  3. 55
      mh-admin/src/main/java/com/mh/web/controller/comprehensive/CompreReportController.java
  4. 23
      mh-admin/src/main/java/com/mh/web/controller/comprehensive/ProOverviewController.java
  5. 14
      mh-admin/src/main/java/com/mh/web/controller/device/ChillersParamsController.java
  6. 11
      mh-admin/src/main/java/com/mh/web/controller/device/OperationController.java
  7. 58
      mh-admin/src/main/java/com/mh/web/controller/energy/HowWaterRevenueEnergyController.java
  8. 8
      mh-admin/src/main/java/com/mh/web/controller/energy/SysEnergyConsumptionController.java
  9. 44
      mh-admin/src/main/java/com/mh/web/controller/energy/SysEnergyQueryController.java
  10. 6
      mh-admin/src/main/java/com/mh/web/controller/monitor/CoolingSystemMonitorController.java
  11. 45
      mh-admin/src/main/java/com/mh/web/controller/monitor/ERSMonitorController.java
  12. 70
      mh-admin/src/main/java/com/mh/web/controller/monitor/HeatingPumpMonitorController.java
  13. 57
      mh-admin/src/main/java/com/mh/web/controller/monitor/SteamBoilerMonitorController.java
  14. 96
      mh-admin/src/main/java/com/mh/web/controller/report/ReportHeatingController.java
  15. 72
      mh-admin/src/main/java/com/mh/web/controller/report/ReportHotWaterController.java
  16. 131
      mh-admin/src/main/java/com/mh/web/controller/report/ReportMeterReadingsController.java
  17. 156
      mh-admin/src/main/java/com/mh/web/controller/report/ReportSteamController.java
  18. 100
      mh-admin/src/main/java/com/mh/web/controller/report/ReportSysController.java
  19. 8
      mh-admin/src/main/java/com/mh/web/controller/space/BuildingInfoController.java
  20. 2
      mh-admin/src/main/java/com/mh/web/controller/system/SysLoginController.java
  21. 14
      mh-admin/src/main/resources/application-dev.yml
  22. 2
      mh-admin/src/main/resources/application-druid.yml
  23. 22
      mh-admin/src/main/resources/application-prod.yml
  24. 10
      mh-admin/src/main/resources/application-test.yml
  25. 46
      mh-admin/src/main/resources/logback.xml
  26. BIN
      mh-admin/src/main/resources/节能岛改造每日能耗统计表.xlsx
  27. 176
      mh-admin/src/test/java/com/mh/MHApplicationTest.java
  28. 6
      mh-common/pom.xml
  29. 4
      mh-common/src/main/java/com/mh/common/config/wechat/WechatSignUtil.java
  30. 10
      mh-common/src/main/java/com/mh/common/constant/CacheConstants.java
  31. 5
      mh-common/src/main/java/com/mh/common/constant/Constants.java
  32. 232
      mh-common/src/main/java/com/mh/common/core/domain/dto/BFloorReportHotWaterDTO.java
  33. 74
      mh-common/src/main/java/com/mh/common/core/domain/dto/CompreReportDTO.java
  34. 29
      mh-common/src/main/java/com/mh/common/core/domain/dto/HotWaterNowDataDTO.java
  35. 77
      mh-common/src/main/java/com/mh/common/core/domain/dto/HotWaterRevenueSumDTO.java
  36. 284
      mh-common/src/main/java/com/mh/common/core/domain/dto/MaglevReportSysParamDTO.java
  37. 179
      mh-common/src/main/java/com/mh/common/core/domain/dto/ReportHeatingRunParamDTO.java
  38. 135
      mh-common/src/main/java/com/mh/common/core/domain/dto/ReportSteamRunParamDTO.java
  39. 172
      mh-common/src/main/java/com/mh/common/core/domain/dto/ThreeFloorReportHotWaterDTO.java
  40. 19
      mh-common/src/main/java/com/mh/common/core/domain/entity/AlarmRecords.java
  41. 1
      mh-common/src/main/java/com/mh/common/core/domain/entity/CpmSpaceRelation.java
  42. 70
      mh-common/src/main/java/com/mh/common/core/domain/entity/EnergyBaseSum.java
  43. 54
      mh-common/src/main/java/com/mh/common/core/domain/entity/EnergyDaySum.java
  44. 54
      mh-common/src/main/java/com/mh/common/core/domain/entity/EnergyMonthSum.java
  45. 54
      mh-common/src/main/java/com/mh/common/core/domain/entity/EnergyYearSum.java
  46. 217
      mh-common/src/main/java/com/mh/common/core/domain/entity/ReportHeatingRunParamHis.java
  47. 54
      mh-common/src/main/java/com/mh/common/core/domain/entity/ReportHotWaterParamHis.java
  48. 114
      mh-common/src/main/java/com/mh/common/core/domain/entity/ReportMeterReadingsHis.java
  49. 170
      mh-common/src/main/java/com/mh/common/core/domain/entity/ReportSteamRunParamHis.java
  50. 2
      mh-common/src/main/java/com/mh/common/core/domain/entity/SysRole.java
  51. 2
      mh-common/src/main/java/com/mh/common/core/domain/entity/SysUser.java
  52. 20
      mh-common/src/main/java/com/mh/common/core/domain/entity/WeatherData.java
  53. 53
      mh-common/src/main/java/com/mh/common/core/domain/vo/CollectionParamsManageDataVO.java
  54. 5
      mh-common/src/main/java/com/mh/common/core/domain/vo/CollectionParamsManageVO.java
  55. 6
      mh-common/src/main/java/com/mh/common/core/domain/vo/DeviceMonitorVO.java
  56. 14
      mh-common/src/main/java/com/mh/common/core/domain/vo/EnergyConsumptionVO.java
  57. 67
      mh-common/src/main/java/com/mh/common/core/domain/vo/HotWaterControlVO.java
  58. 7
      mh-common/src/main/java/com/mh/common/model/request/AdvantechDatas.java
  59. 74
      mh-common/src/main/java/com/mh/common/model/request/AdvantechJsonParser.java
  60. 39
      mh-common/src/main/java/com/mh/common/model/response/ParseResult.java
  61. 138
      mh-common/src/main/java/com/mh/common/utils/AnalysisReceiveOrder485.java
  62. 11
      mh-common/src/main/java/com/mh/common/utils/BigDecimalUtils.java
  63. 50
      mh-common/src/main/java/com/mh/common/utils/DateUtils.java
  64. 36
      mh-common/src/main/java/com/mh/common/utils/ModbusUtils.java
  65. 6
      mh-common/src/main/java/com/mh/common/utils/SecurityUtils.java
  66. 2
      mh-common/src/main/java/com/mh/common/utils/SendOrderUtils.java
  67. 24
      mh-common/src/main/java/com/mh/common/utils/WeatherUtil.java
  68. 49
      mh-common/src/main/java/com/mh/common/utils/file/handle/ReportDayAndMonthParamHandler.java
  69. 12
      mh-common/src/main/java/com/mh/common/utils/http/HttpUtils.java
  70. 7
      mh-framework/pom.xml
  71. 16
      mh-framework/src/main/java/com/mh/framework/aspectj/ControlDeviceAspect.java
  72. 2
      mh-framework/src/main/java/com/mh/framework/aspectj/RateLimiterAspect.java
  73. 2
      mh-framework/src/main/java/com/mh/framework/datasource/DynamicDataSourceContextHolder.java
  74. 10
      mh-framework/src/main/java/com/mh/framework/dealdata/DataProcessService.java
  75. 142
      mh-framework/src/main/java/com/mh/framework/dealdata/impl/DataProcessServiceImpl.java
  76. 2
      mh-framework/src/main/java/com/mh/framework/manager/factory/AsyncFactory.java
  77. 4
      mh-framework/src/main/java/com/mh/framework/mqtt/handler/InboundMessageRouter.java
  78. 14
      mh-framework/src/main/java/com/mh/framework/mqtt/service/impl/EventsServiceImpl.java
  79. 4
      mh-framework/src/main/java/com/mh/framework/mqtt/service/impl/MqttMsgSenderServiceImpl.java
  80. 6
      mh-framework/src/main/java/com/mh/framework/netty/EchoServer.java
  81. 175
      mh-framework/src/main/java/com/mh/framework/netty/EchoServerHandler.java
  82. 22
      mh-framework/src/main/java/com/mh/framework/netty/NettyServiceImpl.java
  83. 495
      mh-framework/src/main/java/com/mh/framework/netty/NewEchoServerHandler.java
  84. 6
      mh-framework/src/main/java/com/mh/framework/netty/session/ServerSession.java
  85. 8
      mh-framework/src/main/java/com/mh/framework/netty/session/SessionMap.java
  86. 58
      mh-framework/src/main/java/com/mh/framework/rabbitmq/RabbitMqConfig.java
  87. 120
      mh-framework/src/main/java/com/mh/framework/rabbitmq/consumer/ReceiveHandler.java
  88. 33
      mh-framework/src/main/java/com/mh/framework/rabbitmq/producer/SendMsgByTopic.java
  89. 4
      mh-framework/src/main/java/com/mh/framework/web/service/PermissionService.java
  90. 6
      mh-framework/src/main/java/com/mh/framework/web/service/UserDetailsServiceImpl.java
  91. 11
      mh-quartz/src/main/java/com/mh/quartz/domain/FuzzyLevel.java
  92. 52
      mh-quartz/src/main/java/com/mh/quartz/domain/PIDParams.java
  93. 387
      mh-quartz/src/main/java/com/mh/quartz/task/AHUTask.java
  94. 206
      mh-quartz/src/main/java/com/mh/quartz/task/ChillersTask.java
  95. 84
      mh-quartz/src/main/java/com/mh/quartz/task/CreateAlarmTask.java
  96. 42
      mh-quartz/src/main/java/com/mh/quartz/task/DealDataTask.java
  97. 2
      mh-quartz/src/main/java/com/mh/quartz/task/DealOnOrOffData.java
  98. 72
      mh-quartz/src/main/java/com/mh/quartz/task/GGDataTask.java
  99. 38
      mh-quartz/src/main/java/com/mh/quartz/task/HomeTask.java
  100. 4
      mh-quartz/src/main/java/com/mh/quartz/task/HotWaterTask.java
  101. Some files were not shown because too many files have changed in this diff Show More

BIN
doc/节能改造每日能耗统计表.xlsx

Binary file not shown.

4
mh-admin/src/main/java/com/mh/MHRunner.java

@ -45,9 +45,9 @@ public class MHRunner implements ApplicationRunner {
// 初始化mqtt订阅记录 // 初始化mqtt订阅记录
initializeMqttSubscription(); initializeMqttSubscription();
// 生成DTU采集参数 // 生成DTU采集参数
createDtuCollectionParams(); // createDtuCollectionParams();
// 启动netty服务端 // 启动netty服务端
startNettyServer(); // startNettyServer();
} }
private void startNettyServer() { private void startNettyServer() {

55
mh-admin/src/main/java/com/mh/web/controller/comprehensive/CompreReportController.java

@ -0,0 +1,55 @@
package com.mh.web.controller.comprehensive;
import com.mh.common.core.controller.BaseController;
import com.mh.common.core.domain.vo.EnergyQueryVO;
import com.mh.common.core.page.TableDataInfo;
import com.mh.system.service.report.IComprehensiveReportService;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @Classname CompreReportController
* Todo: 综合报表
* @Date 2025-10-05 13:59
* @Created by LJF
*/
@RestController
@RequestMapping("/compre")
public class CompreReportController extends BaseController {
private final IComprehensiveReportService proOverviewService;
public CompreReportController(IComprehensiveReportService proOverviewService) {
this.proOverviewService = proOverviewService;
}
@PostMapping("/report")
public TableDataInfo report(@RequestBody EnergyQueryVO vo) {
TableDataInfo dataTable = getDataTable(proOverviewService.report(vo));
// 优化分页逻辑,防止出现数组越界异常
List<?> rows = dataTable.getRows();
int total = rows.size();
// 如果 pageNum 小于等于0,则返回全部
if (vo.getPageNum() <= 0) {
return dataTable;
}
int pageNum = vo.getPageNum() <= 0 ? 1 : vo.getPageNum();
int pageSize = vo.getPageSize() <= 0 ? 10 : vo.getPageSize();
// 计算起始索引和结束索引
int startIndex = (pageNum - 1) * pageSize;
int endIndex = Math.min(startIndex + pageSize, total);
// 边界检查
if (startIndex >= total || startIndex < 0) {
dataTable.setRows(List.of()); // 返回空列表而不是抛出异常
} else {
dataTable.setRows(rows.subList(startIndex, endIndex));
}
return dataTable;
}
}

23
mh-admin/src/main/java/com/mh/web/controller/comprehensive/ProOverviewController.java

@ -91,4 +91,27 @@ public class ProOverviewController extends BaseController {
return getDataTable(proOverviewService.mainParams()); return getDataTable(proOverviewService.mainParams());
} }
/**
* 获取热回收系统相关数据
* 出水温度离心机高温出水温度中温换热出水温度低温1换热出水温度低温2换热出水温度
* 热量数据生产累积热量散热累积热量总热量回收热利用率
* 系统数据离心机入口温度离心机出水温度保障进水温度
* 阀门开度二通阀阀门开度三通阀阀门开度
* 热回收数据瞬时热量日累积热量累积热量
* 应用侧数据瞬时热量日累计热量累积热量
*
*/
@GetMapping("/ersDatas")
public TableDataInfo ersDatas(@RequestParam("systemType") String systemType) {
return getDataTable(proOverviewService.ersDatas(systemType));
}
/**
* 查询能耗系数
* @return
*/
@GetMapping("/getCoe")
public TableDataInfo getCoe(){
return getDataTable(proOverviewService.getCoe());
}
} }

14
mh-admin/src/main/java/com/mh/web/controller/device/ChillersParamsController.java

@ -52,13 +52,15 @@ public class ChillersParamsController extends BaseController {
*/ */
@GetMapping("/list") @GetMapping("/list")
public TableDataInfo list(CollectionParamsManage collectionParamsManage) { public TableDataInfo list(CollectionParamsManage collectionParamsManage) {
collectionParamsManage.setIsUse(0);
List<CollectionParamsManage> list = iCollectionParamsManageService.selectCollectionParamsManageList(collectionParamsManage); List<CollectionParamsManage> list = iCollectionParamsManageService.selectCollectionParamsManageList(collectionParamsManage);
// list中的CollectionParamsManage中的other_name去掉“号主机”之前数据 // list中的CollectionParamsManage中的other_name去掉“号主机”之前数据
list.forEach(item -> { list.forEach(item -> {
String otherName = item.getOtherName(); String otherName = item.getOtherName();
// 使用正则表达式去掉“号主机”及之前的内容 // 使用正则表达式去掉“号主机”及之前的内容
String result = otherName != null ? otherName.replaceFirst(".*号主机", "") : otherName; String result = otherName != null ? otherName.replaceFirst(".*号主机", "") : otherName;
result = result != null ? result.replace("-", "") : result; result = result != null ? result.replace("_", "") : result;
result = result != null ? result.replace("主机参数", "") : result;
item.setOtherName(result); item.setOtherName(result);
}); });
// list中的CollectionParamsManage对象赋值到CollectionParamsManageVO2形成List<CollectionParamsManageVO2> // list中的CollectionParamsManage对象赋值到CollectionParamsManageVO2形成List<CollectionParamsManageVO2>
@ -68,6 +70,10 @@ public class ChillersParamsController extends BaseController {
CollectionParamsManageVO2 vo = new CollectionParamsManageVO2(); CollectionParamsManageVO2 vo = new CollectionParamsManageVO2();
BeanUtils.copyProperties(item, vo); BeanUtils.copyProperties(item, vo);
vo.setCurValue(item.getCurValue().setScale(2).toString()); vo.setCurValue(item.getCurValue().setScale(2).toString());
// 再根据mtType判断,如果是压缩机的,就只保留整数
if (vo.getMtType().equals("9") || vo.getMtType().equals("10") || vo.getMtType().equals("11")) {
vo.setCurValue(new BigDecimal(vo.getCurValue()).intValue() + "");
}
// 判断运行状态、启停、故障、本地远程 // 判断运行状态、启停、故障、本地远程
switch (vo.getParamType()) { switch (vo.getParamType()) {
case "1": // 运行状态 case "1": // 运行状态
@ -82,7 +88,7 @@ public class ChillersParamsController extends BaseController {
break; break;
case "5": // 故障 case "5": // 故障
if (!StringUtils.isEmpty(vo.getCurValue())) { if (!StringUtils.isEmpty(vo.getCurValue())) {
vo.setCurValue(new BigDecimal(vo.getCurValue()).intValue() == 1 ? "故障" : "正常"); vo.setCurValue(new BigDecimal(vo.getCurValue()).intValue() == 1 ? "故障" : "无故障");
} }
break; break;
case "6": // 手自动切换 case "6": // 手自动切换
@ -114,8 +120,8 @@ public class ChillersParamsController extends BaseController {
return map; return map;
}).collect(Collectors.toList()); }).collect(Collectors.toList());
result.sort((map1, map2) -> { result.sort((map1, map2) -> {
Integer mtType1 = Integer.parseInt((String)map1.get("mtType")); Integer mtType1 = Integer.parseInt((String) map1.get("mtType"));
Integer mtType2 = Integer.parseInt((String)map2.get("mtType")); Integer mtType2 = Integer.parseInt((String) map2.get("mtType"));
return mtType1.compareTo(mtType2); // 升序 return mtType1.compareTo(mtType2); // 升序
}); });
return getDataTable(result); return getDataTable(result);

11
mh-admin/src/main/java/com/mh/web/controller/device/OperationController.java

@ -99,8 +99,15 @@ public class OperationController extends BaseController {
@ControlDeviceAno(value = "设备操作") @ControlDeviceAno(value = "设备操作")
public AjaxResult operationDevice(@RequestBody List<OrderEntity> changeValues) { public AjaxResult operationDevice(@RequestBody List<OrderEntity> changeValues) {
try { try {
// 判断id是否是DTU设备类型 // 增加判断是否是昆仑通态触摸屏的MQTT设备
if (!iOperationService.isAdvanTech(changeValues)) { if (!iOperationService.isKuLunTouchScreen(changeValues)) {
String sendOrder = iOperationService.operationKLTTDevice(changeValues);
String name = mhConfig.getName();
// 获取mqtt操作队列(后期通过mqtt队列配置发送主题)
log.info("发送主题:{},消息:{}", name + "/" + controlTopic, sendOrder);
iMqttGatewayService.publish(name + "/" + controlTopic, sendOrder, 1);
} else if (!iOperationService.isAdvanTech(changeValues)) {
// 判断id是否是DTU设备类型
String sendOrder = iOperationService.operationDevice(changeValues); String sendOrder = iOperationService.operationDevice(changeValues);
String name = mhConfig.getName(); String name = mhConfig.getName();
// 获取mqtt操作队列(后期通过mqtt队列配置发送主题) // 获取mqtt操作队列(后期通过mqtt队列配置发送主题)

58
mh-admin/src/main/java/com/mh/web/controller/energy/HowWaterRevenueEnergyController.java

@ -1,58 +0,0 @@
package com.mh.web.controller.energy;
import com.mh.common.core.controller.BaseController;
import com.mh.common.core.page.PageDomain;
import com.mh.common.core.page.TableDataInfo;
import com.mh.common.core.page.TableSupport;
import com.mh.system.service.energy.IEnergyQueryService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* @author LJF
* @version 1.0
* @project EEMCS
* @description 中央热水收益分析
* @date 2026-05-13 08:37:12
*/
@RestController
@RequestMapping("/hot_water_revenue")
public class HowWaterRevenueEnergyController extends BaseController {
private final IEnergyQueryService energyQueryService;
public HowWaterRevenueEnergyController(IEnergyQueryService iEnergyQueryService) {
this.energyQueryService = iEnergyQueryService;
}
@GetMapping(value = "/energySum")
public TableDataInfo queryEnergySum(@RequestParam(value = "buildingId", required = false) String buildingId,
@RequestParam(value = "startDate", required = false) String startDate,
@RequestParam(value = "endDate", required = false) String endDate,
@RequestParam(value = "type", required = true) Integer type) {
startPage();
List<?> result = energyQueryService.queryRevenueEnergyDataSumList(buildingId, startDate, endDate, type);
return getDataTable(result);
}
@GetMapping("/query")
public TableDataInfo queryEnergy(@RequestParam(value = "buildingId", required = false) String buildingId,
@RequestParam(value = "startDate", required = false) String startDate,
@RequestParam(value = "endDate", required = false) String endDate,
@RequestParam(value = "type") int type) {
startPage();
List<?> result = energyQueryService.queryRevenueEnergyDataList(buildingId, startDate, endDate, type);
TableDataInfo dataTable = getDataTable(result);
// 或者总条数数据
PageDomain pageDomain = TableSupport.buildPageRequest();
pageDomain.setPageNum(0);
List<?> result1 = energyQueryService.queryRevenueEnergyDataList(buildingId, startDate, endDate, type);
dataTable.setTotal(result1.size());
return dataTable;
}
}

8
mh-admin/src/main/java/com/mh/web/controller/energy/SysEnergyConsumptionController.java

@ -77,7 +77,13 @@ public class SysEnergyConsumptionController extends BaseController {
@PostMapping("/device") @PostMapping("/device")
public AjaxResult device(@RequestBody EnergyConsumptionVO vo) { public AjaxResult device(@RequestBody EnergyConsumptionVO vo) {
DateUtils.energyDateChange(vo); DateUtils.energyDateChange(vo);
return energyService.device(vo); if (vo.getSystemType().equals("0")) {
// 冷源系统
return energyService.device(vo);
} else {
// 热回收系统
return energyService.deviceERS(vo);
}
} }
} }

44
mh-admin/src/main/java/com/mh/web/controller/energy/SysEnergyQueryController.java

@ -54,6 +54,9 @@ public class SysEnergyQueryController {
// 文件名 // 文件名
try { try {
String fileName = "机房整体能耗表.xlsx"; String fileName = "机房整体能耗表.xlsx";
if (vo.getSystemType().equalsIgnoreCase("7")) {
fileName = "热回收热量总计表.xlsx";
}
// 从数据库获取数据 // 从数据库获取数据
List<Map<String, Object>> dataList = (List<Map<String, Object>>) energyQueryService.sysQuery(vo).get("data"); List<Map<String, Object>> dataList = (List<Map<String, Object>>) energyQueryService.sysQuery(vo).get("data");
if (dataList != null) { if (dataList != null) {
@ -71,18 +74,33 @@ public class SysEnergyQueryController {
for (Map<String, Object> map : dataList) { for (Map<String, Object> map : dataList) {
if (map.containsKey("titleArr")) { if (map.containsKey("titleArr")) {
titleArr = Arrays.asList((String[]) map.get("titleArr")); titleArr = Arrays.asList((String[]) map.get("titleArr"));
List<String> head0 = ListUtils.newArrayList(); if (vo.getSystemType().equalsIgnoreCase("7")) {
head0.add("日期"); List<String> head0 = ListUtils.newArrayList();
List<String> head1 = ListUtils.newArrayList(); head0.add("日期");
head1.add("制冷量"); List<String> head1 = ListUtils.newArrayList();
List<String> head2 = ListUtils.newArrayList(); head1.add("散热量");
head2.add("耗电量"); List<String> head2 = ListUtils.newArrayList();
List<String> head3= ListUtils.newArrayList(); head2.add("总热量回收");
head3.add("COP"); List<String> head3 = ListUtils.newArrayList();
head.add(head0); head3.add("热利用率");
head.add(head1); head.add(head0);
head.add(head2); head.add(head1);
head.add(head3); head.add(head2);
head.add(head3);
} else {
List<String> head0 = ListUtils.newArrayList();
head0.add("日期");
List<String> head1 = ListUtils.newArrayList();
head1.add("制冷量");
List<String> head2 = ListUtils.newArrayList();
head2.add("耗电量");
List<String> head3 = ListUtils.newArrayList();
head3.add("COP");
head.add(head0);
head.add(head1);
head.add(head2);
head.add(head3);
}
} }
if (map.containsKey("timeStrArr")) { if (map.containsKey("timeStrArr")) {
timeStrArr = Arrays.asList((String[])map.get("timeStrArr")); timeStrArr = Arrays.asList((String[])map.get("timeStrArr"));
@ -107,7 +125,7 @@ public class SysEnergyQueryController {
excelDataList.add(list1); excelDataList.add(list1);
} }
// 内容格式 // 内容格式
EasyExcel.write(response.getOutputStream()).head(head).sheet("机房整体能耗表").doWrite(excelDataList); EasyExcel.write(response.getOutputStream()).head(head).sheet(fileName.substring(0, fileName.lastIndexOf("."))).doWrite(excelDataList);
} }
} catch (Exception e) { } catch (Exception e) {
log.error("下载报表异常", e); log.error("下载报表异常", e);

6
mh-admin/src/main/java/com/mh/web/controller/monitor/CoolingSystemMonitorController.java

@ -111,4 +111,10 @@ public class CoolingSystemMonitorController extends BaseController {
return AjaxResult.success(iCoolingSystemMonitorService.getSystemMode(systemType, paramType)); return AjaxResult.success(iCoolingSystemMonitorService.getSystemMode(systemType, paramType));
} }
@GetMapping("/getWeatherTemp")
public TableDataInfo getWeatherTemp(@RequestParam(name = "startTime") String startTime, @RequestParam(name = "endTime") String endTime){
startPage();
return getDataTable(iCoolingSystemMonitorService.getWeatherTemp(startTime, endTime));
}
} }

45
mh-admin/src/main/java/com/mh/web/controller/monitor/ERSMonitorController.java

@ -0,0 +1,45 @@
package com.mh.web.controller.monitor;
import com.mh.common.core.controller.BaseController;
import com.mh.common.core.domain.dto.DeviceMonitorDTO;
import com.mh.common.core.page.TableDataInfo;
import com.mh.system.service.device.ICollectionParamsManageService;
import jakarta.annotation.Resource;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* @author LJF
* @version 1.0
* @project EEMCS
* @description 热回收系统工业流程图
* @date 2026-01-28 13:48:13
*/
@RestController
@RequestMapping("/device/ers")
public class ERSMonitorController extends BaseController {
@Resource
private ICollectionParamsManageService iCollectionParamsManageService;
@PreAuthorize("@ss.hasPermi('device:cpm:list')")
@GetMapping("/monitor/list")
public TableDataInfo list(@RequestParam(name = "systemType") String systemType)
{
List<DeviceMonitorDTO> list = iCollectionParamsManageService.selectMonitorListBySystemType(systemType);
return getDataTable(list);
}
@GetMapping("/monitor/totalDatas")
public TableDataInfo totalERSDatas(@RequestParam(name = "systemType") String systemType)
{
List<?> list = iCollectionParamsManageService.totalERSDatas(systemType);
return getDataTable(list);
}
}

70
mh-admin/src/main/java/com/mh/web/controller/monitor/HeatingPumpMonitorController.java

@ -0,0 +1,70 @@
package com.mh.web.controller.monitor;
import com.mh.common.core.controller.BaseController;
import com.mh.common.core.domain.dto.DeviceMonitorDTO;
import com.mh.common.core.domain.entity.CollectionParamsManage;
import com.mh.common.core.page.TableDataInfo;
import com.mh.system.service.device.ICollectionParamsManageService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* @author LJF
* @version 1.0
* @project EEMCS
* @description 三台采暖泵的监测
* @date 2025-09-12 09:36:33
*/
@RestController
@RequestMapping("/device")
public class HeatingPumpMonitorController extends BaseController {
private final ICollectionParamsManageService collectionParamsManageService;
public HeatingPumpMonitorController(ICollectionParamsManageService collectionParamsManageService) {
this.collectionParamsManageService = collectionParamsManageService;
}
/**
* 获取 alarmList 列表
* @param systemType 3
* @param type 0代表查询报警
* @return
*/
@RequestMapping("/heatPump/alarmList")
public TableDataInfo list(@RequestParam(name = "systemType") String systemType,
@RequestParam(name = "type", required = false, defaultValue = "0") String type) {
List<?> list = collectionParamsManageService.selectHeatPumpAlarmListByParams(systemType, type, "14", "5");
return getDataTable(list);
}
/**
* 获取 运行热泵统计 列表
* @param systemType 3
* @param type 0代表查询报警
* @return
*/
@RequestMapping("/heatPump/online")
public TableDataInfo online(@RequestParam(name = "systemType") String systemType,
@RequestParam(name = "type", required = false, defaultValue = "0") String type) {
List<?> list = collectionParamsManageService.selectHeatPumpOnlineByParams(systemType, type);
return getDataTable(list);
}
/**
* 获取 采暖泵 列表
* @param systemType 3
* @param type 0代表查询动画界面数据
* @return
*/
@RequestMapping("/heatPump/list")
public TableDataInfo heatPumpList(@RequestParam(name = "systemType") String systemType,
@RequestParam(name = "type", required = false, defaultValue = "0") String type) {
List<DeviceMonitorDTO> list = collectionParamsManageService.selectHotWaterBoilerListByParams(systemType, type, "14");
return getDataTable(list);
}
}

57
mh-admin/src/main/java/com/mh/web/controller/monitor/SteamBoilerMonitorController.java

@ -0,0 +1,57 @@
package com.mh.web.controller.monitor;
import com.mh.common.core.controller.BaseController;
import com.mh.common.core.domain.dto.DeviceMonitorDTO;
import com.mh.common.core.domain.entity.CollectionParamsManage;
import com.mh.common.core.page.TableDataInfo;
import com.mh.system.service.device.ICollectionParamsManageService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* @author LJF
* @version 1.0
* @project EEMCS
* @description 蒸汽热水锅炉监测
* @date 2025-09-12 09:36:33
*/
@RestController
@RequestMapping("/device")
public class SteamBoilerMonitorController extends BaseController {
private final ICollectionParamsManageService collectionParamsManageService;
public SteamBoilerMonitorController(ICollectionParamsManageService collectionParamsManageService) {
this.collectionParamsManageService = collectionParamsManageService;
}
/**
* 获取 steamBoiler 列表
* @param systemType 3
* @param type 0代表查询动画界面数据1代表查询模拟量监测数据2代表查询继电器数据3查询端口输入数据4代表查询报警数据
* @return
*/
@RequestMapping("/steamBoiler/list")
public TableDataInfo list(@RequestParam(name = "systemType") String systemType,
@RequestParam(name = "type") String type) {
List<CollectionParamsManage> list = collectionParamsManageService.selectSteamBoilerListByParams(systemType, type);
return getDataTable(list);
}
/**
* 获取 热水锅炉 列表
* @param systemType 3
* @param type 0代表查询动画界面数据
* @return
*/
@RequestMapping("/hotWaterBoiler/list")
public TableDataInfo hotWaterBoilerList(@RequestParam(name = "systemType") String systemType,
@RequestParam(name = "type", required = false, defaultValue = "0") String type) {
List<DeviceMonitorDTO> list = collectionParamsManageService.selectHotWaterBoilerListByParams(systemType, type, "13");
return getDataTable(list);
}
}

96
mh-admin/src/main/java/com/mh/web/controller/report/ReportHeatingController.java

@ -0,0 +1,96 @@
package com.mh.web.controller.report;
import com.alibaba.excel.EasyExcel;
import com.github.pagehelper.PageHelper;
import com.mh.common.core.controller.BaseController;
import com.mh.common.core.domain.AjaxResult;
import com.mh.common.core.domain.dto.ReportHeatingRunParamDTO;
import com.mh.common.core.domain.dto.ReportSteamRunParamDTO;
import com.mh.common.core.domain.entity.ReportHeatingRunParamHis;
import com.mh.common.core.domain.entity.ReportSteamRunParamHis;
import com.mh.common.core.page.PageDomain;
import com.mh.common.core.page.TableDataInfo;
import com.mh.common.core.page.TableSupport;
import com.mh.common.utils.file.handle.ExcelFillCellMergeHandler;
import com.mh.common.utils.file.handle.ReportSysParamHandler;
import com.mh.common.utils.file.handle.RowHeightStyleHandler;
import com.mh.common.utils.sql.SqlUtil;
import com.mh.system.service.report.IReportHeatingService;
import com.mh.system.service.report.IReportSteamService;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author LJF
* @version 1.0
* @project eemcs
* @description 采暖系统运行参数报表
* @date 2024-05-30 08:45:57
*/
@RestController
@RequestMapping("/reportHeating")
@Slf4j
public class ReportHeatingController extends BaseController {
private final IReportHeatingService reportHeatingService;
private ReportHeatingController(IReportHeatingService reportHeatingService) {
this.reportHeatingService = reportHeatingService;
}
@PostMapping("/list")
public TableDataInfo list(@RequestBody ReportHeatingRunParamHis reportHeatingRunParamHis) {
if (reportHeatingRunParamHis.getPageNum() != 0) {
PageHelper.startPage(reportHeatingRunParamHis.getPageNum(), reportHeatingRunParamHis.getPageSize());
}
List<ReportHeatingRunParamHis> list = reportHeatingService.selectHeatingList(reportHeatingRunParamHis);
return getDataTable(list);
}
@PutMapping("/edit")
public AjaxResult edit(@RequestBody ReportHeatingRunParamHis reportHeatingRunParamHis) {
return toAjax(reportHeatingService.updateRunParams(reportHeatingRunParamHis));
}
@PostMapping("/export")
public void exportExcel(@RequestBody ReportHeatingRunParamHis reportSteamRunParamHis, HttpServletResponse response) {
// 文件名
try {
String fileName = "采暖系统运行记录表.xlsx";
String headTitle = "采暖系统运行记录表";
// 从数据库获取数据
List<ReportHeatingRunParamHis> list = reportHeatingService.selectHeatingList(reportSteamRunParamHis);
if (list != null) {
// 设置响应格式
response.setContentType("application/vdn.ms-excel;charset=utf-8");
response.setHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode(fileName, StandardCharsets.UTF_8) + "\"");
response.setCharacterEncoding(String.valueOf(StandardCharsets.UTF_8));
ExcelFillCellMergeHandler mergePrevCol = new ExcelFillCellMergeHandler();
List<ReportHeatingRunParamDTO> infoDTOS = list.stream().map(info -> {
ReportHeatingRunParamDTO deviceInfoDTO = new ReportHeatingRunParamDTO();
BeanUtils.copyProperties(info, deviceInfoDTO);
return deviceInfoDTO;
}).collect(Collectors.toList());
// 内容格式
EasyExcel.write(response.getOutputStream(), ReportHeatingRunParamDTO.class)
.registerWriteHandler(new ReportSysParamHandler(headTitle))
.registerWriteHandler(mergePrevCol)
.registerWriteHandler(new RowHeightStyleHandler())
.sheet(fileName.replace(".xlsx", ""))
.doWrite(infoDTOS);
}
} catch (IOException e) {
throw new RuntimeException("下载报表异常");
}
}
}

72
mh-admin/src/main/java/com/mh/web/controller/report/ReportHotWaterController.java

@ -6,7 +6,6 @@ import com.mh.common.core.controller.BaseController;
import com.mh.common.core.domain.AjaxResult; import com.mh.common.core.domain.AjaxResult;
import com.mh.common.core.domain.dto.BFloorReportHotWaterDTO; import com.mh.common.core.domain.dto.BFloorReportHotWaterDTO;
import com.mh.common.core.domain.dto.ThreeFloorReportHotWaterDTO; import com.mh.common.core.domain.dto.ThreeFloorReportHotWaterDTO;
import com.mh.common.core.domain.entity.FloorInfo;
import com.mh.common.core.domain.entity.ReportHotWaterParamHis; import com.mh.common.core.domain.entity.ReportHotWaterParamHis;
import com.mh.common.core.domain.entity.ReportSysRunParamHis; import com.mh.common.core.domain.entity.ReportSysRunParamHis;
import com.mh.common.core.page.TableDataInfo; import com.mh.common.core.page.TableDataInfo;
@ -15,7 +14,6 @@ import com.mh.common.utils.file.handle.ExcelFillCellMergeHandler;
import com.mh.common.utils.file.handle.ReportSysParamHandler; import com.mh.common.utils.file.handle.ReportSysParamHandler;
import com.mh.common.utils.file.handle.RowHeightStyleHandler; import com.mh.common.utils.file.handle.RowHeightStyleHandler;
import com.mh.system.service.report.IReportHotWaterService; import com.mh.system.service.report.IReportHotWaterService;
import com.mh.system.service.space.IFloorInfoService;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
@ -39,12 +37,9 @@ import java.util.stream.Collectors;
public class ReportHotWaterController extends BaseController { public class ReportHotWaterController extends BaseController {
private final IReportHotWaterService reportHotWaterService; private final IReportHotWaterService reportHotWaterService;
private final IFloorInfoService floorInfoService;
private ReportHotWaterController(IReportHotWaterService reportHotWaterService, IFloorInfoService floorInfoService) { private ReportHotWaterController(IReportHotWaterService reportHotWaterService) {
this.reportHotWaterService = reportHotWaterService; this.reportHotWaterService = reportHotWaterService;
this.floorInfoService = floorInfoService;
} }
@PostMapping("/list") @PostMapping("/list")
@ -53,12 +48,6 @@ public class ReportHotWaterController extends BaseController {
if (reportHotWaterParamHis.getPageNum() != 0) { if (reportHotWaterParamHis.getPageNum() != 0) {
PageHelper.startPage(reportHotWaterParamHis.getPageNum(), reportHotWaterParamHis.getPageSize()); PageHelper.startPage(reportHotWaterParamHis.getPageNum(), reportHotWaterParamHis.getPageSize());
} }
FloorInfo floorInfo = floorInfoService.selectFloorInfoById(reportHotWaterParamHis.getFloorId());
if (floorInfo == null) {
throw new IllegalArgumentException("Floor not found");
} else {
reportHotWaterParamHis.setFloorId(reportHotWaterParamHis.getFloorId() + "_" + floorInfo.getFloorName());
}
List<ReportHotWaterParamHis> list = reportHotWaterService.selectList(reportHotWaterParamHis); List<ReportHotWaterParamHis> list = reportHotWaterService.selectList(reportHotWaterParamHis);
return getDataTable(list); return getDataTable(list);
} }
@ -66,12 +55,6 @@ public class ReportHotWaterController extends BaseController {
@PutMapping("/edit") @PutMapping("/edit")
public AjaxResult edit(@RequestBody ReportHotWaterParamHis reportHotWaterParamHis) public AjaxResult edit(@RequestBody ReportHotWaterParamHis reportHotWaterParamHis)
{ {
// FloorInfo floorInfo = floorInfoService.selectFloorInfoById(reportHotWaterParamHis.getFloorId());
// if (floorInfo == null) {
// throw new IllegalArgumentException("Floor not found");
// } else {
// reportHotWaterParamHis.setFloorId(reportHotWaterParamHis.getFloorId() + "_" + floorInfo.getFloorName());
// }
return toAjax(reportHotWaterService.updateRunParams(reportHotWaterParamHis)); return toAjax(reportHotWaterService.updateRunParams(reportHotWaterParamHis));
} }
@ -81,21 +64,14 @@ public class ReportHotWaterController extends BaseController {
try { try {
String fileName = "热水热泵运行记录表.xlsx"; String fileName = "热水热泵运行记录表.xlsx";
String floorId = reportHotWaterParamHis.getFloorId(); String floorId = reportHotWaterParamHis.getFloorId();
FloorInfo floorInfo = floorInfoService.selectFloorInfoById(floorId);
if (floorInfo == null) {
throw new IllegalArgumentException("Floor not found");
} else {
floorId = floorId + "_" + floorInfo.getFloorName();
reportHotWaterParamHis.setFloorId(floorId);
}
String headTitle = "热水热泵运行记录表"; String headTitle = "热水热泵运行记录表";
if (!StringUtils.isBlank(floorId)) { if (!StringUtils.isBlank(floorId)) {
if (floorId.contains("楼")) { if (floorId.contains("-1楼")) {
fileName = "楼热水热泵运行记录表.xlsx"; fileName = "-1楼热水热泵运行记录表.xlsx";
headTitle = "楼热水热泵运行记录表"; headTitle = "-1楼热水热泵运行记录表";
} else { } else {
fileName = "贵宾楼热水热泵运行记录表.xlsx"; fileName = "3楼热水热泵运行记录表.xlsx";
headTitle = "贵宾楼热水热泵运行记录表"; headTitle = "3楼热水热泵运行记录表";
} }
} }
// 从数据库获取数据 // 从数据库获取数据
@ -107,7 +83,7 @@ public class ReportHotWaterController extends BaseController {
response.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8");
ExcelFillCellMergeHandler mergePrevCol = new ExcelFillCellMergeHandler(); ExcelFillCellMergeHandler mergePrevCol = new ExcelFillCellMergeHandler();
int headSize = 3; int headSize = 3;
if (floorId.contains("贵宾楼")) { if (floorId.contains("-1楼")) {
List<BFloorReportHotWaterDTO> infoDTOS = list.stream().map(info -> { List<BFloorReportHotWaterDTO> infoDTOS = list.stream().map(info -> {
BFloorReportHotWaterDTO deviceInfoDTO = new BFloorReportHotWaterDTO(); BFloorReportHotWaterDTO deviceInfoDTO = new BFloorReportHotWaterDTO();
BeanUtils.copyProperties(info, deviceInfoDTO); BeanUtils.copyProperties(info, deviceInfoDTO);
@ -116,18 +92,10 @@ public class ReportHotWaterController extends BaseController {
deviceInfoDTO.setStatusSwitchHotPumpOneStr(info.getStatusSwitchHotPumpOne() == 1 ? "开机" : "关机"); deviceInfoDTO.setStatusSwitchHotPumpOneStr(info.getStatusSwitchHotPumpOne() == 1 ? "开机" : "关机");
deviceInfoDTO.setStatusRunHotPumpTwoStr(info.getStatusRunHotPumpTwo() == 1 ? "运行" : "不运行"); deviceInfoDTO.setStatusRunHotPumpTwoStr(info.getStatusRunHotPumpTwo() == 1 ? "运行" : "不运行");
deviceInfoDTO.setStatusSwitchHotPumpTwoStr(info.getStatusSwitchHotPumpTwo() == 1 ? "开机" : "关机"); deviceInfoDTO.setStatusSwitchHotPumpTwoStr(info.getStatusSwitchHotPumpTwo() == 1 ? "开机" : "关机");
deviceInfoDTO.setStatusRunHotPumpThreeStr(info.getStatusRunHotPumpThree() == 1 ? "运行" : "不运行"); deviceInfoDTO.setStatusRunSupplyPumpOneStr(info.getStatusRunSupplyPumpOne() == 1 ? "运行" : "不运行");
deviceInfoDTO.setStatusSwitchHotPumpThreeStr(info.getStatusSwitchHotPumpThree() == 1 ? "开机" : "关机"); deviceInfoDTO.setStatusRunSupplyPumpTwoStr(info.getStatusRunSupplyPumpTwo() == 1 ? "运行" : "不运行");
deviceInfoDTO.setStatusRunHotPumpFourStr(info.getStatusRunHotPumpFour() == 1 ? "运行" : "不运行"); deviceInfoDTO.setStatusRunSupplyPumpThreeStr(info.getStatusRunSupplyPumpThree() == 1 ? "运行" : "不运行");
deviceInfoDTO.setStatusSwitchHotPumpFourStr(info.getStatusSwitchHotPumpFour() == 1 ? "开机" : "关机"); deviceInfoDTO.setStatusRunSupplyPumpFourStr(info.getStatusRunSupplyPumpFour() == 1 ? "运行" : "不运行");
deviceInfoDTO.setStatusRunHotPumpFiveStr(info.getStatusRunHotPumpFive() == 1 ? "运行" : "不运行");
deviceInfoDTO.setStatusSwitchHotPumpFiveStr(info.getStatusSwitchHotPumpFive() == 1 ? "开机" : "关机");
deviceInfoDTO.setStatusRunHotPumpSixStr(info.getStatusRunHotPumpSix() == 1 ? "运行" : "不运行");
deviceInfoDTO.setStatusSwitchHotPumpSixStr(info.getStatusSwitchHotPumpSix() == 1 ? "开机" : "关机");
deviceInfoDTO.setStatusRunHotPumpSevenStr(info.getStatusRunHotPumpSeven() == 1 ? "运行" : "不运行");
deviceInfoDTO.setStatusSwitchHotPumpSevenStr(info.getStatusSwitchHotPumpSeven() == 1 ? "开机" : "关机");
deviceInfoDTO.setStatusRunHotPumpEightStr(info.getStatusRunHotPumpEight() == 1 ? "运行" : "不运行");
deviceInfoDTO.setStatusSwitchHotPumpEightStr(info.getStatusSwitchHotPumpEight() == 1 ? "开机" : "关机");
return deviceInfoDTO; return deviceInfoDTO;
}).collect(Collectors.toList()); }).collect(Collectors.toList());
@ -147,16 +115,14 @@ public class ReportHotWaterController extends BaseController {
deviceInfoDTO.setStatusSwitchHotPumpOneStr(info.getStatusSwitchHotPumpOne() == 1 ? "开机" : "关机"); deviceInfoDTO.setStatusSwitchHotPumpOneStr(info.getStatusSwitchHotPumpOne() == 1 ? "开机" : "关机");
deviceInfoDTO.setStatusRunHotPumpTwoStr(info.getStatusRunHotPumpTwo() == 1 ? "运行" : "不运行"); deviceInfoDTO.setStatusRunHotPumpTwoStr(info.getStatusRunHotPumpTwo() == 1 ? "运行" : "不运行");
deviceInfoDTO.setStatusSwitchHotPumpTwoStr(info.getStatusSwitchHotPumpTwo() == 1 ? "开机" : "关机"); deviceInfoDTO.setStatusSwitchHotPumpTwoStr(info.getStatusSwitchHotPumpTwo() == 1 ? "开机" : "关机");
deviceInfoDTO.setStatusRunCyclePumpOneStr(info.getStatusRunCyclePumpOne() == 1 ? "运行" : "不运行"); deviceInfoDTO.setStatusRunHotPumpThreeStr(info.getStatusRunHotPumpThree() == 1 ? "运行" : "不运行");
deviceInfoDTO.setStatusRunCyclePumpTwoStr(info.getStatusRunCyclePumpTwo() == 1 ? "运行" : "不运行"); deviceInfoDTO.setStatusSwitchHotPumpThreeStr(info.getStatusSwitchHotPumpThree() == 1 ? "开机" : "关机");
// deviceInfoDTO.setStatusRunHotPumpThreeStr(info.getStatusRunHotPumpThree() == 1 ? "运行" : "不运行"); deviceInfoDTO.setStatusRunHotPumpFourStr(info.getStatusRunHotPumpFour() == 1 ? "运行" : "不运行");
// deviceInfoDTO.setStatusSwitchHotPumpThreeStr(info.getStatusSwitchHotPumpThree() == 1 ? "开机" : "关机"); deviceInfoDTO.setStatusSwitchHotPumpFourStr(info.getStatusSwitchHotPumpFour() == 1 ? "开机" : "关机");
// deviceInfoDTO.setStatusRunHotPumpFourStr(info.getStatusRunHotPumpFour() == 1 ? "运行" : "不运行"); deviceInfoDTO.setStatusRunSupplyPumpOneStr(info.getStatusRunSupplyPumpOne() == 1 ? "运行" : "不运行");
// deviceInfoDTO.setStatusSwitchHotPumpFourStr(info.getStatusSwitchHotPumpFour() == 1 ? "开机" : "关机"); deviceInfoDTO.setStatusRunSupplyPumpTwoStr(info.getStatusRunSupplyPumpTwo() == 1 ? "运行" : "不运行");
// deviceInfoDTO.setStatusRunSupplyPumpOneStr(info.getStatusRunSupplyPumpOne() == 1 ? "运行" : "不运行"); deviceInfoDTO.setStatusRunSupplyPumpThreeStr(info.getStatusRunSupplyPumpThree() == 1 ? "运行" : "不运行");
// deviceInfoDTO.setStatusRunSupplyPumpTwoStr(info.getStatusRunSupplyPumpTwo() == 1 ? "运行" : "不运行"); deviceInfoDTO.setStatusRunSupplyPumpFourStr(info.getStatusRunSupplyPumpFour() == 1 ? "运行" : "不运行");
// deviceInfoDTO.setStatusRunSupplyPumpThreeStr(info.getStatusRunSupplyPumpThree() == 1 ? "运行" : "不运行");
// deviceInfoDTO.setStatusRunSupplyPumpFourStr(info.getStatusRunSupplyPumpFour() == 1 ? "运行" : "不运行");
return deviceInfoDTO; return deviceInfoDTO;
}).collect(Collectors.toList()); }).collect(Collectors.toList());

131
mh-admin/src/main/java/com/mh/web/controller/report/ReportMeterReadingsController.java

@ -0,0 +1,131 @@
package com.mh.web.controller.report;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillWrapper;
import com.mh.common.core.controller.BaseController;
import com.mh.common.core.domain.dto.WeatherDataDTO;
import com.mh.common.core.domain.entity.ReportMeterReadingsHis;
import com.mh.common.core.page.TableDataInfo;
import com.mh.common.utils.DateUtils;
import com.mh.system.service.device.ICoolingSystemMonitorService;
import com.mh.system.service.report.IMeterReadingsHisService;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.poi.ss.usermodel.*;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.bind.annotation.*;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
/**
* @author LJF
* @version 1.0
* @project EEMCS
* @description 每日抄表记录查询
* @date 2025-10-21 16:04:09
*/
@RestController
@RequestMapping("/reportMeterReadings")
public class ReportMeterReadingsController extends BaseController {
private final IMeterReadingsHisService meterReadingsHisService;
private final ICoolingSystemMonitorService coolingSystemMonitorService;
public ReportMeterReadingsController(IMeterReadingsHisService meterReadingsHisService, ICoolingSystemMonitorService coolingSystemMonitorService) {
this.meterReadingsHisService = meterReadingsHisService;
this.coolingSystemMonitorService = coolingSystemMonitorService;
}
@PostMapping("/list")
public TableDataInfo list(@RequestBody ReportMeterReadingsHis todayTimestamp)
{
List<ReportMeterReadingsHis> list = meterReadingsHisService.selectList(todayTimestamp);
return getDataTable(list);
}
@PostMapping("/export")
public void exportExcel(@RequestBody ReportMeterReadingsHis reportMeterReadingsHis, HttpServletResponse response) {
// 文件名
try {
String fileName = "节能岛改造每日能耗统计表"+ DateUtils.dateToString(reportMeterReadingsHis.getTodayTimestamp(), "yyyyMMdd")+".xlsx";
// 读取资源文件
ClassPathResource classPathResource = new ClassPathResource(File.separator + "节能岛改造每日能耗统计表.xlsx");
// 获取数据
List<ReportMeterReadingsHis> list = meterReadingsHisService.selectList(reportMeterReadingsHis);
// 组织并填充模板数据
ByteArrayOutputStream byteArrayOutputStream = compositeFill(classPathResource.getInputStream(), reportMeterReadingsHis.getTodayTimestamp(), list);
// 设置响应格式
response.setContentType("application/vdn.ms-excel;charset=utf-8");
response.setHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode(fileName, "UTF-8") + "\"");
response.setCharacterEncoding("UTF-8");
// 将文件内容写入响应输出流,浏览器可以直接触发下载
response.getOutputStream().write(byteArrayOutputStream.toByteArray());
response.getOutputStream().flush();
} catch (IOException e) {
throw new RuntimeException("下载报表异常");
}
}
private ByteArrayOutputStream compositeFill(InputStream templateInputStream, Date todayTimestamp, List<ReportMeterReadingsHis> list) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
// 使用EasyExcel的模板填充功能,在这里指定合并单元格,这里应该是easyExcel的bug,第一列无法合并,其他列都可以,所以第一列单独用原生poi进行合并
try (ExcelWriter excelWriter = EasyExcel.write(byteArrayOutputStream).withTemplate(templateInputStream)
.build()) {
WriteSheet writeSheet = EasyExcel.writerSheet().build();
// 防止上面两个表格覆盖下面两个表格,每一行都采用新增一行的方式
// FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
// 使用模板填充,必须使用FillWrapper,这是官方要求,并且每行两个表格只能有一个表格设置增行,否则会存在一个表格有空行,这里是造的测试数据
for (int i = 0; i < list.size(); i++) {
excelWriter.fill(new FillWrapper("data"+(i+1), List.of(list.get(i))), writeSheet);
}
// 设置表格外的填充数据,例如总计、日期等数据
HashMap<String, Object> map = new HashMap<>();
List<WeatherDataDTO> weatherTemp = (List<WeatherDataDTO>) coolingSystemMonitorService.getWeatherTemp(DateUtils.dateToString(todayTimestamp, "yyyy-MM-dd"), DateUtils.dateToString(todayTimestamp, "yyyy-MM-dd"));
if (!weatherTemp.isEmpty()) {
String maxTemp = weatherTemp.getFirst().getMaxTemp();
map.put("maxTemp", maxTemp);
String minTemp = weatherTemp.getFirst().getMinTemp();
map.put("minTemp", minTemp);
}
map.put("date", DateUtils.dateToString(todayTimestamp, "yyyy年MM月dd日"));
excelWriter.fill(map, writeSheet);
// 2. 获取 Workbook 并计算公式
Workbook workbook = excelWriter.writeContext()
.writeWorkbookHolder()
.getWorkbook();
FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
for (Row row : workbook.getSheetAt(0)) {
for (Cell cell : row) {
if (cell.getCellType() == CellType.FORMULA) {
evaluator.evaluateFormulaCell(cell); // 单元格级计算
// evaluator.evaluateAll(); // 全工作簿计算(推荐)
}
}
}
// 3. 强制刷新计算结果
workbook.setForceFormulaRecalculation(true);
excelWriter.finish();
}
// 合并单元格,由于easyExcel自带的OnceAbsoluteMergeStrategy合并策略bug,这里需要用poi合并一下
return byteArrayOutputStream;
}
}

156
mh-admin/src/main/java/com/mh/web/controller/report/ReportSteamController.java

@ -0,0 +1,156 @@
package com.mh.web.controller.report;
import com.alibaba.excel.EasyExcel;
import com.github.pagehelper.PageHelper;
import com.mh.common.core.controller.BaseController;
import com.mh.common.core.domain.AjaxResult;
import com.mh.common.core.domain.dto.ReportSteamRunParamDTO;
import com.mh.common.core.domain.dto.ThreeFloorReportHotWaterDTO;
import com.mh.common.core.domain.entity.ReportSteamRunParamHis;
import com.mh.common.core.page.TableDataInfo;
import com.mh.common.utils.file.handle.ExcelFillCellMergeHandler;
import com.mh.common.utils.file.handle.ReportSysParamHandler;
import com.mh.common.utils.file.handle.RowHeightStyleHandler;
import com.mh.system.service.report.IReportSteamService;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author LJF
* @version 1.0
* @project eemcs
* @description 蒸汽系统运行参数报表
* @date 2024-05-30 08:45:57
*/
@RestController
@RequestMapping("/reportSteam")
@Slf4j
public class ReportSteamController extends BaseController {
private final IReportSteamService reportSteamService;
private ReportSteamController(IReportSteamService reportSteamService) {
this.reportSteamService = reportSteamService;
}
@PostMapping("/list")
public TableDataInfo list(@RequestBody ReportSteamRunParamHis reportSteamRunParamHis) {
if (reportSteamRunParamHis.getPageNum() != 0) {
PageHelper.startPage(reportSteamRunParamHis.getPageNum(), reportSteamRunParamHis.getPageSize());
}
List<ReportSteamRunParamHis> list = reportSteamService.selectList(reportSteamRunParamHis);
return getDataTable(list);
}
@PutMapping("/edit")
public AjaxResult edit(@RequestBody ReportSteamRunParamHis reportSteamRunParamHis) {
return toAjax(reportSteamService.updateRunParams(reportSteamRunParamHis));
}
@PostMapping("/export")
public void exportExcel(@RequestBody ReportSteamRunParamHis reportSteamRunParamHis, HttpServletResponse response) {
// 文件名
try {
String fileName = "蒸汽机运行记录表.xlsx";
String headTitle = "蒸汽机运行记录表";
// 从数据库获取数据
List<ReportSteamRunParamHis> list = reportSteamService.selectList(reportSteamRunParamHis);
if (list != null) {
// 设置响应格式
response.setContentType("application/vdn.ms-excel;charset=utf-8");
response.setHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode(fileName, "UTF-8") + "\"");
response.setCharacterEncoding("UTF-8");
ExcelFillCellMergeHandler mergePrevCol = new ExcelFillCellMergeHandler();
List<ReportSteamRunParamDTO> infoDTOS = list.stream().map(info -> {
ReportSteamRunParamDTO deviceInfoDTO = new ReportSteamRunParamDTO();
BeanUtils.copyProperties(info, deviceInfoDTO);
// 单独处理运行状态
// 0:上电延时
// 1:关机
// 2:待机
// 3:前清扫
// 4:预点火
// 5:点火
// 6:传火
// 7:工作
// 8:后清扫
// 9:故障
// 10:小火保持
// 11:自检
// 12:检漏
// 13:开点火器
// 14:启动等待中
switch (info.getCurStatus()) {
case 0:
deviceInfoDTO.setCurStatus("上电延时");
break;
case 1:
deviceInfoDTO.setCurStatus("关机");
break;
case 2:
deviceInfoDTO.setCurStatus("待机");
break;
case 3:
deviceInfoDTO.setCurStatus("前清扫");
break;
case 4:
deviceInfoDTO.setCurStatus("预点火");
break;
case 5:
deviceInfoDTO.setCurStatus("点火");
break;
case 6:
deviceInfoDTO.setCurStatus("传火");
break;
case 7:
deviceInfoDTO.setCurStatus("工作");
break;
case 8:
deviceInfoDTO.setCurStatus("后清扫");
break;
case 9:
deviceInfoDTO.setCurStatus("故障");
break;
case 10:
deviceInfoDTO.setCurStatus("小火保持");
break;
case 11:
deviceInfoDTO.setCurStatus("自检");
break;
case 12:
deviceInfoDTO.setCurStatus("检漏");
break;
case 13:
deviceInfoDTO.setCurStatus("开点火器");
break;
case 14:
deviceInfoDTO.setCurStatus("启动等待中");
break;
default:
deviceInfoDTO.setCurStatus("未知");
break;
}
return deviceInfoDTO;
}).collect(Collectors.toList());
// 内容格式
EasyExcel.write(response.getOutputStream(), ReportSteamRunParamDTO.class)
.registerWriteHandler(new ReportSysParamHandler(headTitle))
.registerWriteHandler(mergePrevCol)
.registerWriteHandler(new RowHeightStyleHandler())
.sheet(fileName.replace(".xlsx", ""))
.doWrite(infoDTOS);
}
} catch (IOException e) {
throw new RuntimeException("下载报表异常");
}
}
}

100
mh-admin/src/main/java/com/mh/web/controller/report/ReportSysController.java

@ -0,0 +1,100 @@
package com.mh.web.controller.report;
import com.alibaba.excel.EasyExcel;
import com.github.pagehelper.PageHelper;
import com.mh.common.core.controller.BaseController;
import com.mh.common.core.domain.AjaxResult;
import com.mh.common.core.domain.dto.MaglevReportSysParamDTO;
import com.mh.common.core.domain.entity.ReportSysRunParamHis;
import com.mh.common.core.page.TableDataInfo;
import com.mh.common.utils.StringUtils;
import com.mh.common.utils.file.handle.ExcelFillCellMergeHandler;
import com.mh.common.utils.file.handle.ReportSysParamHandler;
import com.mh.common.utils.file.handle.RowHeightStyleHandler;
import com.mh.system.service.report.IReportSysService;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author LJF
* @version 1.0
* @project NewZhujiang_Server
* @description 系统参数报表
* @date 2024-05-30 08:45:57
*/
@RestController
@RequestMapping("/reportSys")
@Slf4j
public class ReportSysController extends BaseController {
private final IReportSysService reportSysService;
private ReportSysController(IReportSysService reportSysService) {
this.reportSysService = reportSysService;
}
@PostMapping("/list")
public TableDataInfo list(@RequestBody ReportSysRunParamHis reportSysRunParamHis)
{
if (reportSysRunParamHis.getPageNum() != 0) {
PageHelper.startPage(reportSysRunParamHis.getPageNum(), reportSysRunParamHis.getPageSize());
}
List<ReportSysRunParamHis> list = reportSysService.selectList(reportSysRunParamHis);
return getDataTable(list);
}
@PutMapping("/edit")
public AjaxResult edit(@RequestBody ReportSysRunParamHis reportSysRunParamHis)
{
return toAjax(reportSysService.updateSysRunParams(reportSysRunParamHis));
}
@PostMapping("/export")
public void exportExcel(@RequestBody ReportSysRunParamHis reportSysRunParamHis, HttpServletResponse response) {
// 文件名
try {
String fileName = "系统参数运行日志报表.xlsx";
String deviceNum = (String) reportSysRunParamHis.getParams().get("deviceNum");
if (!StringUtils.isBlank(deviceNum)) {
if ("2".equals(deviceNum)) {
fileName = "变频螺杆主机系统参数报表.xlsx";
} else {
fileName = "磁悬浮主机系统参数报表.xlsx";
}
}
// 从数据库获取数据
List<ReportSysRunParamHis> list = reportSysService.selectList(reportSysRunParamHis);
if (list != null) {
// 设置响应格式
response.setContentType("application/vdn.ms-excel;charset=utf-8");
response.setHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode(fileName, "UTF-8") + "\"");
response.setCharacterEncoding("UTF-8");
ExcelFillCellMergeHandler mergePrevCol = new ExcelFillCellMergeHandler();
int headSize = 3;
List<MaglevReportSysParamDTO> infoDTOS = list.stream().map(info -> {
MaglevReportSysParamDTO deviceInfoDTO = new MaglevReportSysParamDTO();
BeanUtils.copyProperties(info, deviceInfoDTO);
return deviceInfoDTO;
}).collect(Collectors.toList());
// 内容格式
EasyExcel.write(response.getOutputStream(), MaglevReportSysParamDTO.class)
.registerWriteHandler(new ReportSysParamHandler("磁悬浮水冷冷水机组数据运行记录表"))
.registerWriteHandler(mergePrevCol)
.registerWriteHandler(new RowHeightStyleHandler())
.sheet(fileName.replace(".xlsx", ""))
.doWrite(infoDTOS);
}
} catch (IOException e) {
throw new RuntimeException("下载报表异常");
}
}
}

8
mh-admin/src/main/java/com/mh/web/controller/space/BuildingInfoController.java

@ -94,11 +94,13 @@ public class BuildingInfoController extends BaseController {
* 获取楼栋管理列表内容数据 * 获取楼栋管理列表内容数据
*/ */
@GetMapping("/hot_list") @GetMapping("/hot_list")
public TableDataInfo hotWaterList() public TableDataInfo hotWaterList(@RequestParam("systemType") String systemType)
{ {
List<Map<String, Object>> list = energyQueryService.queryFloorInfo(); List<Map<String, Object>> list = energyQueryService.queryFloorInfo(systemType);
// 在当前list首个坐标加个值 // 在当前list首个坐标加个值
list.addFirst(Map.of("id", "所有", "building_name", "所有")); if (systemType.equals("1")) {
list.addFirst(Map.of("id", "所有", "building_name", "所有"));
}
return getDataTable(list); return getDataTable(list);
} }

2
mh-admin/src/main/java/com/mh/web/controller/system/SysLoginController.java

@ -92,6 +92,6 @@ public class SysLoginController
{ {
Long userId = SecurityUtils.getUserId(); Long userId = SecurityUtils.getUserId();
List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId); List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId);
return AjaxResult.success(menuService.buildMenus(menus)); return AjaxResult.success(menuService.buildMenus(menus,userId));
} }
} }

14
mh-admin/src/main/resources/application-dev.yml

@ -1,11 +1,11 @@
# 项目相关配置 # 项目相关配置
mh: mh:
# 名称 # 名称
name: MH name: gh_ers_dev
# 版本 # 版本
version: 1.0.0 version: 1.0.0
# 版权年份 # 版权年份
copyrightYear: 2024 copyrightYear: 2026
# 文件路径 示例( Windows配置D:/mh/uploadPath,Linux配置 /home/mh/uploadPath) # 文件路径 示例( Windows配置D:/mh/uploadPath,Linux配置 /home/mh/uploadPath)
profile: D:/mh/uploadPath profile: D:/mh/uploadPath
# 获取ip地址开关 # 获取ip地址开关
@ -63,7 +63,7 @@ spring:
# 端口,默认为6379 # 端口,默认为6379
port: 6379 port: 6379
# 数据库索引 # 数据库索引
database: 0 database: 1
# 密码 # 密码
password: password:
# 连接超时时间 # 连接超时时间
@ -84,7 +84,7 @@ spring:
port: 5672 port: 5672
username: eemcs username: eemcs
password: mh@803 password: mh@803
virtual-host: /eemcs virtual-host: /eemcs_gh_ers
listener: listener:
direct: direct:
prefetch: 2 prefetch: 2
@ -98,8 +98,8 @@ spring:
# 主库数据源 # 主库数据源
master: master:
#添加allowMultiQueries=true 在批量更新时才不会出错 #添加allowMultiQueries=true 在批量更新时才不会出错
url: jdbc:postgresql://127.0.0.1:5432/eemcs_hw_dev url: jdbc:postgresql://127.0.0.1:5432/eemcs_gh_ers_dev
# url: jdbc:postgresql://127.0.0.1:5432/eemcs # url: jdbc:postgresql://106.55.173.225:5505/eemcs
username: postgres username: postgres
password: mh@803 password: mh@803
# 从库数据源 # 从库数据源
@ -200,7 +200,7 @@ mqttSpring:
# port: 1883 # port: 1883
# username: sa # username: sa
# password: sa123 # password: sa123
client-id: mqtt_mz_producer_dev client-id: mqtt_gh_ers_producer_dev
# If the protocol is ws/wss, this value is required. # If the protocol is ws/wss, this value is required.
path: path:
# Topics that need to be subscribed when initially connecting to mqtt, multiple topics are divided by ",". # Topics that need to be subscribed when initially connecting to mqtt, multiple topics are divided by ",".

2
mh-admin/src/main/resources/application-druid.yml

@ -7,7 +7,7 @@ spring:
# 主库数据源 # 主库数据源
master: master:
#添加allowMultiQueries=true 在批量更新时才不会出错 #添加allowMultiQueries=true 在批量更新时才不会出错
url: jdbc:postgresql://127.0.0.1:5432/eemcs_hw url: jdbc:postgresql://127.0.0.1:5432/eemcs_gh_ers_dev
# url: jdbc:postgresql://127.0.0.1:5432/eemcs # url: jdbc:postgresql://127.0.0.1:5432/eemcs
username: postgres username: postgres
password: mh@803 password: mh@803

22
mh-admin/src/main/resources/application-prod.yml

@ -1,11 +1,11 @@
# 项目相关配置 # 项目相关配置
mh: mh:
# 名称 # 名称
name: hw name: gh_ers
# 版本 # 版本
version: 1.0.0 version: 1.0.0
# 版权年份 # 版权年份
copyrightYear: 2024 copyrightYear: 2026
# 文件路径 示例( Windows配置D:/mh/uploadPath,Linux配置 /home/mh/uploadPath) # 文件路径 示例( Windows配置D:/mh/uploadPath,Linux配置 /home/mh/uploadPath)
profile: E:/mh/uploadPath profile: E:/mh/uploadPath
# 获取ip地址开关 # 获取ip地址开关
@ -16,7 +16,7 @@ mh:
# 开发环境配置 # 开发环境配置
server: server:
# 服务器的HTTP端口,默认为8080 # 服务器的HTTP端口,默认为8080
port: 8090 port: 8091
servlet: servlet:
# 应用的访问路径 # 应用的访问路径
context-path: / context-path: /
@ -63,7 +63,7 @@ spring:
# 端口,默认为6379 # 端口,默认为6379
port: 6379 port: 6379
# 数据库索引 # 数据库索引
database: 0 database: 1
# 密码 # 密码
password: password:
# 连接超时时间 # 连接超时时间
@ -84,7 +84,7 @@ spring:
port: 5672 port: 5672
username: eemcs username: eemcs
password: mh@803 password: mh@803
virtual-host: /eemcs virtual-host: /eemcs_gh_ers
listener: listener:
direct: direct:
prefetch: 2 prefetch: 2
@ -98,8 +98,8 @@ spring:
# 主库数据源 # 主库数据源
master: master:
#添加allowMultiQueries=true 在批量更新时才不会出错 #添加allowMultiQueries=true 在批量更新时才不会出错
url: jdbc:postgresql://127.0.0.1:5505/eemcs_hw url: jdbc:postgresql://127.0.0.1:5505/eemcs_gh_ers
# url: jdbc:postgresql://127.0.0.1:5505/eemcs # url: jdbc:postgresql://127.0.0.1:5505/eemcs
username: postgres username: postgres
password: mhtech@803 password: mhtech@803
# 从库数据源 # 从库数据源
@ -193,9 +193,9 @@ mqttSpring:
protocol: MQTT protocol: MQTT
host: mqtt.mhito.net host: mqtt.mhito.net
port: 1883 port: 1883
username: sa username: eemcs_gh_ers
password: sa123 password: mhtech@ghers
client-id: eemcs_hw_mqtt_pro client-id: eemcs_gh_ers_mqtt_pro
# If the protocol is ws/wss, this value is required. # If the protocol is ws/wss, this value is required.
path: path:
# Topics that need to be subscribed when initially connecting to mqtt, multiple topics are divided by ",". # Topics that need to be subscribed when initially connecting to mqtt, multiple topics are divided by ",".
@ -208,7 +208,7 @@ mqttSpring:
port: 8083 port: 8083
path: /mqtt path: /mqtt
control: control:
topic: mh_control/events_upload/devices topic: mh_control/events_upload/devices/dev
amap: amap:
key: fc4e79719daca2d0b8a11ba3124e1bd5 key: fc4e79719daca2d0b8a11ba3124e1bd5

10
mh-admin/src/main/resources/application-test.yml

@ -1,11 +1,11 @@
# 项目相关配置 # 项目相关配置
mh: mh:
# 名称 # 名称
name: MH name: gh_ers
# 版本 # 版本
version: 1.0.0 version: 1.0.0
# 版权年份 # 版权年份
copyrightYear: 2024 copyrightYear: 2026
# 文件路径 示例( Windows配置D:/mh/uploadPath,Linux配置 /home/mh/uploadPath) # 文件路径 示例( Windows配置D:/mh/uploadPath,Linux配置 /home/mh/uploadPath)
profile: D:/mh/uploadPath profile: D:/mh/uploadPath
# 获取ip地址开关 # 获取ip地址开关
@ -63,7 +63,7 @@ spring:
# 端口,默认为6379 # 端口,默认为6379
port: 6379 port: 6379
# 数据库索引 # 数据库索引
database: 0 database: 1
# 密码 # 密码
password: password:
# 连接超时时间 # 连接超时时间
@ -98,7 +98,7 @@ spring:
# 主库数据源 # 主库数据源
master: master:
#添加allowMultiQueries=true 在批量更新时才不会出错 #添加allowMultiQueries=true 在批量更新时才不会出错
url: jdbc:postgresql://106.55.173.225:5505/eemcs_hw url: jdbc:postgresql://106.55.173.225:5505/eemcs_gh_ers_dev
username: postgres username: postgres
password: mhtech@803 password: mhtech@803
# 从库数据源 # 从库数据源
@ -194,7 +194,7 @@ mqttSpring:
port: 2883 port: 2883
username: mh username: mh
password: mhtech@803 password: mhtech@803
client-id: mqtt_mz_producer_dev client-id: mqtt_gh_ers_producer_test
# If the protocol is ws/wss, this value is required. # If the protocol is ws/wss, this value is required.
path: path:
# Topics that need to be subscribed when initially connecting to mqtt, multiple topics are divided by ",". # Topics that need to be subscribed when initially connecting to mqtt, multiple topics are divided by ",".

46
mh-admin/src/main/resources/logback.xml

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<!-- 日志存放路径 --> <!-- 日志存放路径 -->
<property name="log.path" value="/home/mh/hw/logs" /> <property name="log.path" value="/home/mh/gh_ers/logs" />
<!-- 日志输出格式 --> <!-- 日志输出格式 -->
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" /> <property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
@ -13,27 +13,27 @@
</appender> </appender>
<!-- 系统日志输出 --> <!-- 系统日志输出 -->
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- <appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">-->
<file>${log.path}/sys-info.log</file> <!-- <file>${log.path}/sys-info.log</file>-->
<!-- 循环政策:基于时间创建日志文件 --> <!-- &lt;!&ndash; 循环政策:基于时间创建日志文件 &ndash;&gt;-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">-->
<!-- 日志文件名格式 --> <!-- &lt;!&ndash; 日志文件名格式 &ndash;&gt;-->
<fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern> <!-- <fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>-->
<!-- 日志最大的历史 60天 --> <!-- &lt;!&ndash; 日志最大的历史 60天 &ndash;&gt;-->
<maxHistory>1</maxHistory> <!-- <maxHistory>1</maxHistory>-->
</rollingPolicy> <!-- </rollingPolicy>-->
<encoder> <!-- <encoder>-->
<pattern>${log.pattern}</pattern> <!-- <pattern>${log.pattern}</pattern>-->
</encoder> <!-- </encoder>-->
<filter class="ch.qos.logback.classic.filter.LevelFilter"> <!-- <filter class="ch.qos.logback.classic.filter.LevelFilter">-->
<!-- 过滤的级别 --> <!-- &lt;!&ndash; 过滤的级别 &ndash;&gt;-->
<level>INFO</level> <!-- <level>INFO</level>-->
<!-- 匹配时的操作:接收(记录) --> <!-- &lt;!&ndash; 匹配时的操作:接收(记录) &ndash;&gt;-->
<onMatch>ACCEPT</onMatch> <!-- <onMatch>ACCEPT</onMatch>-->
<!-- 不匹配时的操作:拒绝(不记录) --> <!-- &lt;!&ndash; 不匹配时的操作:拒绝(不记录) &ndash;&gt;-->
<onMismatch>DENY</onMismatch> <!-- <onMismatch>DENY</onMismatch>-->
</filter> <!-- </filter>-->
</appender> <!-- </appender>-->
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender"> <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-error.log</file> <file>${log.path}/sys-error.log</file>
@ -82,7 +82,7 @@
<!--系统操作日志--> <!--系统操作日志-->
<root level="info"> <root level="info">
<appender-ref ref="file_info" /> <!-- <appender-ref ref="file_info" />-->
<appender-ref ref="file_error" /> <appender-ref ref="file_error" />
</root> </root>

BIN
mh-admin/src/main/resources/节能岛改造每日能耗统计表.xlsx

Binary file not shown.

176
mh-admin/src/test/java/com/mh/MHApplicationTest.java

@ -2,20 +2,26 @@ package com.mh;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.mh.common.core.domain.dto.ProProfileDTO;
import com.mh.common.core.domain.entity.DeviceReport; import com.mh.common.core.domain.entity.DeviceReport;
import com.mh.common.core.domain.entity.SysParams; import com.mh.common.core.domain.entity.SysParams;
import com.mh.common.core.domain.entity.SysUser; import com.mh.common.core.domain.entity.SysUser;
import com.mh.common.core.domain.entity.WeatherData; import com.mh.common.core.domain.entity.WeatherData;
import com.mh.common.core.domain.vo.EnergyQueryVO;
import com.mh.common.utils.DateUtils; import com.mh.common.utils.DateUtils;
import com.mh.common.utils.StringUtils; import com.mh.common.utils.StringUtils;
import com.mh.quartz.task.DealDataTask; import com.mh.quartz.task.DealDataTask;
import com.mh.quartz.task.GGDataTask;
import com.mh.quartz.task.GetWeatherDataTask; import com.mh.quartz.task.GetWeatherDataTask;
import com.mh.quartz.task.HotWaterTask; import com.mh.quartz.task.HotWaterTask;
import com.mh.system.mapper.device.DataProcessMapper; import com.mh.system.mapper.device.DataProcessMapper;
import com.mh.system.service.ISysParamsService; import com.mh.system.service.ISysParamsService;
import com.mh.system.service.ISysUserService; import com.mh.system.service.ISysUserService;
import com.mh.system.service.device.IDeviceQrManageService; import com.mh.system.service.device.IDeviceQrManageService;
import com.mh.system.service.operation.IAlarmRecordsService;
import com.mh.system.service.overview.IProOverviewService;
import com.mh.system.service.report.IComprehensiveReportService;
import com.mh.system.service.report.IMeterReadingsHisService;
import com.mh.system.service.report.IReportHotWaterService;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.checkerframework.checker.units.qual.A; import org.checkerframework.checker.units.qual.A;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -23,7 +29,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import java.math.BigDecimal;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
@ -46,50 +51,132 @@ public class MHApplicationTest {
@Autowired @Autowired
private HotWaterTask hotWaterTask; private HotWaterTask hotWaterTask;
@Autowired
private IAlarmRecordsService alarmRecordsService;
@Autowired
private IMeterReadingsHisService meterReadingsHisService;
@Autowired
private IReportHotWaterService reportHotWaterService;
@Autowired
private IProOverviewService proOverviewService;
@Autowired
private IComprehensiveReportService comprehensiveReportService;
@Test @Test
public void hotWaterTask() { public void comprehensiveReport() {
hotWaterTask.calcEnergyData("2026-04-10 11:00:00"); long startTime = System.currentTimeMillis();
EnergyQueryVO vo = new EnergyQueryVO();
vo.setStartTime("2025-12-24 00:00:00");
vo.setEndTime("2025-12-24 23:59:59");
vo.setPageNum(1);
vo.setPageSize(10);
vo.setTimeType("hour");
System.out.println("开始查询");
List<?> report = comprehensiveReportService.report(vo);
System.out.println("报表耗时:" + (System.currentTimeMillis() - startTime) + "ms");
} }
@Test @Test
public void hotWaterTaskWithTimeRange() { public void testHome() throws Exception {
// 定义起始时间和结束时间 // 开始计时
String startTimeStr = "2026-05-12 00:00:00"; long startTime = System.currentTimeMillis();
String endTimeStr = "2026-05-12 23:00:00"; List<ProProfileDTO> proProfile = proOverviewService.getProProfile();
System.out.println("耗时:" + (System.currentTimeMillis() - startTime) + "ms");
try { }
java.time.LocalDateTime startTime = java.time.LocalDateTime.parse(startTimeStr,
java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); @Test
java.time.LocalDateTime endTime = java.time.LocalDateTime.parse(endTimeStr, public void reportHotWater() {
java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); reportHotWaterService.execProRunParamHis();
}
java.time.LocalDateTime currentTime = startTime;
int count = 0;
while (!currentTime.isAfter(endTime)) {
String timeStr = currentTime.format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
System.out.println("正在处理时间: " + timeStr);
try {
hotWaterTask.calcFloorEnergyData(timeStr);
count++;
} catch (Exception e) {
System.err.println("处理时间 " + timeStr + " 时发生错误: " + e.getMessage());
e.printStackTrace();
}
// 增加一小时
currentTime = currentTime.plusHours(1);
}
System.out.println("完成!共处理了 " + count + " 个时间点的数据"); @Test
public void testExecProMeterReadingsHis() {
meterReadingsHisService.execProMeterReadingsHis("2025-12-11");
}
@Test
public void createAlarmTask() {
alarmRecordsService.insertOrUpdateAlarmRecord("e1a3034edw6a9b3a79a86332886b24896");
}
} catch (Exception e) { @Test
System.err.println("时间范围处理过程中发生错误: " + e.getMessage()); public void calcAnalysisData() {
e.printStackTrace(); for (int i = 9; i < 10; i++) {
hotWaterTask.calcAnalysisData("2025-07-0"+i);
} }
} }
@Test
public void testDate() {
Date date = new Date();
boolean sameDay = DateUtils.isSameDay(DateUtils.stringToDate("2025-09-24 00:00:00", "yyyy-MM-dd HH:mm:ss"), date);
System.out.println(sameDay);
}
@Test
public void calcEnergyData() {
for (int i = 1; i < 17; i++) {
// i < 10,则前面添加0
if (i < 10) {
hotWaterTask.calcEnergyData("2025-10-0"+i+" 00:00:00");
hotWaterTask.calcEnergyData("2025-10-0"+i+" 01:00:00");
hotWaterTask.calcEnergyData("2025-10-0"+i+" 02:00:00");
hotWaterTask.calcEnergyData("2025-10-0"+i+" 03:00:00");
hotWaterTask.calcEnergyData("2025-10-0"+i+" 04:00:00");
hotWaterTask.calcEnergyData("2025-10-0"+i+" 05:00:00");
hotWaterTask.calcEnergyData("2025-10-0"+i+" 06:00:00");
hotWaterTask.calcEnergyData("2025-10-0"+i+" 07:00:00");
hotWaterTask.calcEnergyData("2025-10-0"+i+" 08:00:00");
hotWaterTask.calcEnergyData("2025-10-0"+i+" 09:00:00");
hotWaterTask.calcEnergyData("2025-10-0"+i+" 10:00:00");
hotWaterTask.calcEnergyData("2025-10-0"+i+" 11:00:00");
hotWaterTask.calcEnergyData("2025-10-0"+i+" 12:00:00");
hotWaterTask.calcEnergyData("2025-10-0"+i+" 13:00:00");
hotWaterTask.calcEnergyData("2025-10-0"+i+" 14:00:00");
hotWaterTask.calcEnergyData("2025-10-0"+i+" 15:00:00");
hotWaterTask.calcEnergyData("2025-10-0"+i+" 16:00:00");
hotWaterTask.calcEnergyData("2025-10-0"+i+" 17:00:00");
hotWaterTask.calcEnergyData("2025-10-0"+i+" 18:00:00");
hotWaterTask.calcEnergyData("2025-10-0"+i+" 19:00:00");
hotWaterTask.calcEnergyData("2025-10-0"+i+" 20:00:00");
hotWaterTask.calcEnergyData("2025-10-0"+i+" 21:00:00");
hotWaterTask.calcEnergyData("2025-10-0"+i+" 22:00:00");
hotWaterTask.calcEnergyData("2025-10-0"+i+" 23:00:00");
} else {
hotWaterTask.calcEnergyData("2025-10-" + i + " 00:00:00");
hotWaterTask.calcEnergyData("2025-10-" + i + " 01:00:00");
hotWaterTask.calcEnergyData("2025-10-" + i + " 02:00:00");
hotWaterTask.calcEnergyData("2025-10-" + i + " 03:00:00");
hotWaterTask.calcEnergyData("2025-10-" + i + " 04:00:00");
hotWaterTask.calcEnergyData("2025-10-" + i + " 05:00:00");
hotWaterTask.calcEnergyData("2025-10-" + i + " 06:00:00");
hotWaterTask.calcEnergyData("2025-10-" + i + " 07:00:00");
hotWaterTask.calcEnergyData("2025-10-" + i + " 08:00:00");
hotWaterTask.calcEnergyData("2025-10-" + i + " 09:00:00");
hotWaterTask.calcEnergyData("2025-10-" + i + " 10:00:00");
hotWaterTask.calcEnergyData("2025-10-" + i + " 11:00:00");
hotWaterTask.calcEnergyData("2025-10-" + i + " 12:00:00");
hotWaterTask.calcEnergyData("2025-10-" + i + " 13:00:00");
hotWaterTask.calcEnergyData("2025-10-" + i + " 14:00:00");
hotWaterTask.calcEnergyData("2025-10-" + i + " 15:00:00");
hotWaterTask.calcEnergyData("2025-10-" + i + " 16:00:00");
hotWaterTask.calcEnergyData("2025-10-" + i + " 17:00:00");
hotWaterTask.calcEnergyData("2025-10-" + i + " 18:00:00");
hotWaterTask.calcEnergyData("2025-10-" + i + " 19:00:00");
hotWaterTask.calcEnergyData("2025-10-" + i + " 20:00:00");
hotWaterTask.calcEnergyData("2025-10-" + i + " 21:00:00");
hotWaterTask.calcEnergyData("2025-10-" + i + " 22:00:00");
hotWaterTask.calcEnergyData("2025-10-" + i + " 23:00:00");
}
}
}
@Test @Test
public void test() throws Exception { public void test() throws Exception {
SysUser sysUser = sysUserService.selectUserById(1L); SysUser sysUser = sysUserService.selectUserById(1L);
@ -100,14 +187,6 @@ public class MHApplicationTest {
@Autowired @Autowired
private DealDataTask dealDeviceData; private DealDataTask dealDeviceData;
@Autowired
private GGDataTask gGDataTask;
@Test
public void gGDataTask() {
gGDataTask.calcWeatherData();
}
@Test @Test
public void dealDeviceData() { public void dealDeviceData() {
dealDeviceData.dealDeviceData(); dealDeviceData.dealDeviceData();
@ -129,13 +208,6 @@ public class MHApplicationTest {
@Autowired @Autowired
private ISysParamsService sysParamsService; private ISysParamsService sysParamsService;
@Test
public void test1() {
BigDecimal bigDecimal = new BigDecimal(165);
bigDecimal = bigDecimal.multiply(new BigDecimal(550)).divide(new BigDecimal(1650)).subtract(new BigDecimal(40));
System.out.println(bigDecimal);
}
@Test @Test
public void getWeatherInfo() { public void getWeatherInfo() {
getWeatherDataTask.getWeatherInfo(); getWeatherDataTask.getWeatherInfo();

6
mh-common/pom.xml

@ -159,6 +159,12 @@
<groupId>org.projectlombok</groupId> <groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId> <artifactId>lombok</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>33.4.8-jre</version>
<scope>compile</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.github.binarywang/weixin-java-mp --> <!-- https://mvnrepository.com/artifact/com.github.binarywang/weixin-java-mp -->
<dependency> <dependency>

4
mh-common/src/main/java/com/mh/common/config/wechat/WechatSignUtil.java

@ -44,7 +44,7 @@ public class WechatSignUtil {
// 可选:将字节数组转换为Base64字符串,便于显示和传输 // 可选:将字节数组转换为Base64字符串,便于显示和传输
String base64Encoded = Base64.getEncoder().encodeToString(encodedHash); String base64Encoded = Base64.getEncoder().encodeToString(encodedHash);
// log.info("SHA-1 (Base64 Encoded): {}", base64Encoded); log.info("SHA-1 (Base64 Encoded): {}", base64Encoded);
// 或者,直接以16进制形式输出 // 或者,直接以16进制形式输出
StringBuilder hexString = new StringBuilder(); StringBuilder hexString = new StringBuilder();
@ -53,7 +53,7 @@ public class WechatSignUtil {
if(hex.length() == 1) hexString.append('0'); if(hex.length() == 1) hexString.append('0');
hexString.append(hex); hexString.append(hex);
} }
// log.info("SHA-1 (Hexadecimal): {}", hexString); log.info("SHA-1 (Hexadecimal): {}", hexString);
return hexString.toString(); return hexString.toString();
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
throw new RuntimeException("SHA-1 algorithm not found", e); throw new RuntimeException("SHA-1 algorithm not found", e);

10
mh-common/src/main/java/com/mh/common/constant/CacheConstants.java

@ -41,4 +41,14 @@ public class CacheConstants
* 登录账户密码错误次数 redis key * 登录账户密码错误次数 redis key
*/ */
public static final String PWD_ERR_CNT_KEY = "pwd_err_cnt:"; public static final String PWD_ERR_CNT_KEY = "pwd_err_cnt:";
/**
* 获取项目概况
*/
public static final String PRO_PROFILE = "pro_profile";
/**
* 首页各个采集类型月数据
*/
public static final String ENERGY_ANALYSIS = "energy_analysis";
} }

5
mh-common/src/main/java/com/mh/common/constant/Constants.java

@ -80,6 +80,8 @@ public class Constants {
*/ */
public static final String SUPER_ADMIN = "mhtech"; public static final String SUPER_ADMIN = "mhtech";
public static final String SUPER_ADMIN_TWO = "18675333710";
/** /**
* 角色权限分隔符 * 角色权限分隔符
*/ */
@ -183,10 +185,13 @@ public class Constants {
public static final String CLOSE_HOST = "close_host_device_id"; // 关闭主机的设备id public static final String CLOSE_HOST = "close_host_device_id"; // 关闭主机的设备id
public static final String OPEN_VALVE = "open_valve_device_id"; // 开启蝶阀的设备id public static final String OPEN_VALVE = "open_valve_device_id"; // 开启蝶阀的设备id
public static final String CHILLERS = "chillers"; public static final String CHILLERS = "chillers";
public static final String BOILER = "boiler"; // 锅炉
public static final String OTHER = "other"; public static final String OTHER = "other";
public static final String DEVICE = "devices"; public static final String DEVICE = "devices";
public static final String CHILLERS_TYPE = "0"; // 主机类型设备 public static final String CHILLERS_TYPE = "0"; // 主机类型设备
public static final String OTHER_TYPE = "1"; // 其他设备 public static final String OTHER_TYPE = "1"; // 其他设备
public static final String BOILER_TYPE = "12"; // 锅炉设备
public static final String ERS = "ers"; // 热回收系统
public static boolean CONTROL_WEB_FLAG = false; public static boolean CONTROL_WEB_FLAG = false;
public static boolean SEND_STATUS = false; // 指令发送状态 public static boolean SEND_STATUS = false; // 指令发送状态
public static boolean FLAG = false; public static boolean FLAG = false;

232
mh-common/src/main/java/com/mh/common/core/domain/dto/BFloorReportHotWaterDTO.java

@ -107,231 +107,63 @@ public class BFloorReportHotWaterDTO {
@ColumnWidth(10) @ColumnWidth(10)
private String statusRunHotPumpTwoStr; private String statusRunHotPumpTwoStr;
/** // 高区/裙楼设定压力(bar)
* 设定温度 @ExcelProperty(value = {"${deviceType}", "裙楼变频泵", "设定压力bar"}, index = 9)
*/
@ColumnWidth(10)
@ExcelProperty(value = {"${deviceType}", "3号热泵", "设定温度℃"}, index = 9)
private BigDecimal tempSetHotPumpThree;
/**
* 实际温度
*/
@ExcelProperty(value = {"${deviceType}", "3号热泵", "实际温度℃"}, index = 10)
@ColumnWidth(10)
private BigDecimal tempRealHotPumpThree;
/**
* 设备开关机
*/
@ExcelProperty(value = {"${deviceType}", "3号热泵", "设备开关机"}, index = 11)
@ColumnWidth(10)
private String statusSwitchHotPumpThreeStr;
/**
* 设备运行状态
*/
@ExcelProperty(value = {"${deviceType}", "3号热泵", "设备运行状态"}, index = 12)
@ColumnWidth(10)
private String statusRunHotPumpThreeStr;
/**
* 设定温度
*/
@ColumnWidth(10)
@ExcelProperty(value = {"${deviceType}", "4号热泵", "设定温度℃"}, index = 13)
private BigDecimal tempSetHotPumpFour;
/**
* 实际温度
*/
@ExcelProperty(value = {"${deviceType}", "4号热泵", "实际温度℃"}, index = 14)
@ColumnWidth(10)
private BigDecimal tempRealHotPumpFour;
/**
* 设备开关机
*/
@ExcelProperty(value = {"${deviceType}", "4号热泵", "设备开关机"}, index = 15)
@ColumnWidth(10) @ColumnWidth(10)
private String statusSwitchHotPumpFourStr; private BigDecimal presSetSupplyPumpAreaOne;
/** // 高区/裙楼实际压力(bar)
* 设备运行状态 @ExcelProperty(value = {"${deviceType}", "裙楼变频泵", "实际压力bar"}, index = 10)
*/
@ExcelProperty(value = {"${deviceType}", "4号热泵", "设备运行状态"}, index = 16)
@ColumnWidth(10) @ColumnWidth(10)
private String statusRunHotPumpFourStr; private BigDecimal presRealSupplyPumpAreaOne;
/** // 高区/裙楼1号泵运行状态
* 设定温度 @ExcelProperty(value = {"${deviceType}", "裙楼变频泵", "1号泵运行状态"}, index = 11)
*/
@ColumnWidth(10) @ColumnWidth(10)
@ExcelProperty(value = {"${deviceType}", "5号热泵", "设定温度℃"}, index = 17) private String statusRunSupplyPumpOneStr;
private BigDecimal tempSetHotPumpFive;
/** // 高区/裙楼2号泵运行状态
* 实际温度 @ExcelProperty(value = {"${deviceType}", "裙楼变频泵", "2号泵运行状态"}, index = 12)
*/
@ExcelProperty(value = {"${deviceType}", "5号热泵", "实际温度℃"}, index = 18)
@ColumnWidth(10) @ColumnWidth(10)
private BigDecimal tempRealHotPumpFive; private String statusRunSupplyPumpTwoStr;
/** // 中区/中厨设定压力(bar)
* 设备开关机 @ExcelProperty(value = {"${deviceType}", "中厨变频泵", "设定压力bar"}, index = 13)
*/
@ExcelProperty(value = {"${deviceType}", "5号热泵", "设备开关机"}, index = 19)
@ColumnWidth(10) @ColumnWidth(10)
private String statusSwitchHotPumpFiveStr; private BigDecimal presSetSupplyPumpAreaTwo;
/** // 中区/中厨实际压力(bar)
* 设备运行状态 @ExcelProperty(value = {"${deviceType}", "中厨变频泵", "实际压力bar"}, index = 14)
*/
@ExcelProperty(value = {"${deviceType}", "5号热泵", "设备运行状态"}, index = 20)
@ColumnWidth(10) @ColumnWidth(10)
private String statusRunHotPumpFiveStr; private BigDecimal presRealSupplyPumpAreaTwo;
/** // 中区/中厨1号泵运行状态
* 设定温度 @ExcelProperty(value = {"${deviceType}", "中厨变频泵", "1号泵运行状态"}, index = 15)
*/
@ColumnWidth(10) @ColumnWidth(10)
@ExcelProperty(value = {"${deviceType}", "6号热泵", "设定温度℃"}, index = 21) private String statusRunSupplyPumpThreeStr;
private BigDecimal tempSetHotPumpSix;
/** // 中区/中厨2号泵运行状态
* 实际温度 @ExcelProperty(value = {"${deviceType}", "中厨变频泵", "2号泵运行状态"}, index = 16)
*/
@ExcelProperty(value = {"${deviceType}", "6号热泵", "实际温度℃"}, index = 22)
@ColumnWidth(10) @ColumnWidth(10)
private BigDecimal tempRealHotPumpSix; private String statusRunSupplyPumpFourStr;
/** // 高区/裙楼液位(米)
* 设备开关机 @ExcelProperty(value = {"${deviceType}", "水箱液位", "裙楼液位%"}, index = 17)
*/
@ExcelProperty(value = {"${deviceType}", "6号热泵", "设备开关机"}, index = 23)
@ColumnWidth(10)
private String statusSwitchHotPumpSixStr;
/**
* 设备运行状态
*/
@ExcelProperty(value = {"${deviceType}", "6号热泵", "设备运行状态"}, index = 24)
@ColumnWidth(10)
private String statusRunHotPumpSixStr;
/**
* 设定温度
*/
@ColumnWidth(10)
@ExcelProperty(value = {"${deviceType}", "7号热泵", "设定温度℃"}, index = 25)
private BigDecimal tempSetHotPumpSeven;
/**
* 实际温度
*/
@ExcelProperty(value = {"${deviceType}", "7号热泵", "实际温度℃"}, index = 26)
@ColumnWidth(10)
private BigDecimal tempRealHotPumpSeven;
/**
* 设备开关机
*/
@ExcelProperty(value = {"${deviceType}", "7号热泵", "设备开关机"}, index = 27)
@ColumnWidth(10)
private String statusSwitchHotPumpSevenStr;
/**
* 设备运行状态
*/
@ExcelProperty(value = {"${deviceType}", "7号热泵", "设备运行状态"}, index = 28)
@ColumnWidth(10)
private String statusRunHotPumpSevenStr;
/**
* 设定温度
*/
@ColumnWidth(10)
@ExcelProperty(value = {"${deviceType}", "8号热泵", "设定温度℃"}, index = 29)
private BigDecimal tempSetHotPumpEight;
/**
* 实际温度
*/
@ExcelProperty(value = {"${deviceType}", "8号热泵", "实际温度℃"}, index = 30)
@ColumnWidth(10)
private BigDecimal tempRealHotPumpEight;
/**
* 设备开关机
*/
@ExcelProperty(value = {"${deviceType}", "8号热泵", "设备开关机"}, index = 31)
@ColumnWidth(10)
private String statusSwitchHotPumpEightStr;
/**
* 设备运行状态
*/
@ExcelProperty(value = {"${deviceType}", "8号热泵", "设备运行状态"}, index = 32)
@ColumnWidth(10)
private String statusRunHotPumpEightStr;
// // 高区/裙楼设定压力(bar)
// @ExcelProperty(value = {"${deviceType}", "裙楼变频泵", "设定压力bar"}, index = 9)
// @ColumnWidth(10)
// private BigDecimal presSetSupplyPumpAreaOne;
//
// // 高区/裙楼实际压力(bar)
// @ExcelProperty(value = {"${deviceType}", "裙楼变频泵", "实际压力bar"}, index = 10)
// @ColumnWidth(10)
// private BigDecimal presRealSupplyPumpAreaOne;
//
// // 高区/裙楼1号泵运行状态
// @ExcelProperty(value = {"${deviceType}", "裙楼变频泵", "1号泵运行状态"}, index = 11)
// @ColumnWidth(10)
// private String statusRunSupplyPumpOneStr;
//
// // 高区/裙楼2号泵运行状态
// @ExcelProperty(value = {"${deviceType}", "裙楼变频泵", "2号泵运行状态"}, index = 12)
// @ColumnWidth(10)
// private String statusRunSupplyPumpTwoStr;
//
// // 中区/中厨设定压力(bar)
// @ExcelProperty(value = {"${deviceType}", "中厨变频泵", "设定压力bar"}, index = 13)
// @ColumnWidth(10)
// private BigDecimal presSetSupplyPumpAreaTwo;
//
// // 中区/中厨实际压力(bar)
// @ExcelProperty(value = {"${deviceType}", "中厨变频泵", "实际压力bar"}, index = 14)
// @ColumnWidth(10)
// private BigDecimal presRealSupplyPumpAreaTwo;
//
// // 中区/中厨1号泵运行状态
// @ExcelProperty(value = {"${deviceType}", "中厨变频泵", "1号泵运行状态"}, index = 15)
// @ColumnWidth(10)
// private String statusRunSupplyPumpThreeStr;
//
// // 中区/中厨2号泵运行状态
// @ExcelProperty(value = {"${deviceType}", "中厨变频泵", "2号泵运行状态"}, index = 16)
// @ColumnWidth(10)
// private String statusRunSupplyPumpFourStr;
// 贵宾楼液位1(米)
@ExcelProperty(value = {"${deviceType}", "水箱液位", "水箱1液位(米)"}, index = 33)
@ColumnWidth(10) @ColumnWidth(10)
private BigDecimal levelWaterTankOne; private BigDecimal levelWaterTankOne;
// 主楼液位2(米) // 中区/中厨液位(米)
// @ExcelProperty(value = {"${deviceType}", "水箱液位", "水箱2液位(米)"}, index = 34) @ExcelProperty(value = {"${deviceType}", "水箱液位", "中厨液位%"}, index = 18)
// @ColumnWidth(10) @ColumnWidth(10)
// private BigDecimal levelWaterTankTwo; private BigDecimal levelWaterTankTwo;
// 巡查记录人 // 巡查记录人
@ExcelProperty(value = {"${deviceType}", "巡查记录人", "巡查记录人"}, index = 34) @ExcelProperty(value = {"${deviceType}", "巡查记录人", "巡查记录人"}, index = 19)
@ColumnWidth(20) @ColumnWidth(20)
private String recorder; private String recorder;
// 备注信息 // 备注信息
@ExcelProperty(value = {"${deviceType}", "备注", "备注"}, index = 35) @ExcelProperty(value = {"${deviceType}", "备注", "备注"}, index = 20)
@ColumnWidth(20) @ColumnWidth(20)
private String remark; private String remark;

74
mh-common/src/main/java/com/mh/common/core/domain/dto/CompreReportDTO.java

@ -0,0 +1,74 @@
package com.mh.common.core.domain.dto;
import java.util.StringJoiner;
/**
* @author LJF
* @version 1.0
* @project EEMCS
* @description 综合系统能耗查询DTO
* @date 2025-10-09 10:17:26
*/
public class CompreReportDTO {
private String time;
private String electValue;
private String coldValue;
private String hotValue;
private String steamValue;
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public String getElectValue() {
return electValue;
}
public void setElectValue(String electValue) {
this.electValue = electValue;
}
public String getColdValue() {
return coldValue;
}
public void setColdValue(String coldValue) {
this.coldValue = coldValue;
}
public String getHotValue() {
return hotValue;
}
public void setHotValue(String hotValue) {
this.hotValue = hotValue;
}
public String getSteamValue() {
return steamValue;
}
public void setSteamValue(String steamValue) {
this.steamValue = steamValue;
}
@Override
public String toString() {
return new StringJoiner(", ", CompreReportDTO.class.getSimpleName() + "[", "]")
.add("time='" + time + "'")
.add("electValue='" + electValue + "'")
.add("coldValue='" + coldValue + "'")
.add("hotValue='" + hotValue + "'")
.add("steamValue='" + steamValue + "'")
.toString();
}
}

29
mh-common/src/main/java/com/mh/common/core/domain/dto/HotWaterNowDataDTO.java

@ -20,19 +20,14 @@ public class HotWaterNowDataDTO {
private String pumpName; //热泵名称 private String pumpName; //热泵名称
private String tempSet; //水温设定 private String tempSet; //水温设定
private String waterTemp; //水箱水温 private String waterTemp; //水箱水温
private String runState; //运行状态:0:关机,4:运行,9:待机 private String runState; //运行状态
private String openCloseState;// 开关机状态 0:关机,4:制热
private String isFault; //是否故障 private String isFault; //是否故障
private String levelSet; //水位1设置 private String levelSet1; //水位设置
private String levelSet2; //水位2设置 private String levelSet2; //水位设置
private String waterLevel1; //实际1水位 private String waterLevel1; //实际水位
private String waterLevel2; //实际2水位 private String waterLevel2; //实际水位
private String tankId; //水箱编号 private String tankId; //水箱编号
private String tankName; //水箱名称 private String tankName; //水箱名称
private String tankWaterTemp; // 水箱1温度
private String tankWaterTemp2; // 水箱2温度
private String tankId2; //水箱2编号
private String tankName2; //水箱2名称
private String envTemp; //环境温度 private String envTemp; //环境温度
private String upWaterState1; // 供水1泵状态 private String upWaterState1; // 供水1泵状态
@ -43,15 +38,17 @@ public class HotWaterNowDataDTO {
private String freq2; // 供水频率2 private String freq2; // 供水频率2
private String useWaterState; // 补水状态 private String upWaterState3; // 供水3泵状态
private String backWaterState; // 回水状态 private String freq3; // 供水频率3
private String upWaterState4; // 供水4泵状态
private String loopPumpState1; // 1循环泵状态:0:关机 1:运行 2:故障 private String freq4; // 供水频率4
private String loopPumpState2; // 2循环泵状态:0:关机 1:运行 2:故障 private String useWaterState; // 补水状态
private String gatewayStatus; // 网关状态 0:离线,1:在线 private String backWaterState; // 回水状态
private int orderNum; private int orderNum;

77
mh-common/src/main/java/com/mh/common/core/domain/dto/HotWaterRevenueSumDTO.java

@ -1,77 +0,0 @@
package com.mh.common.core.domain.dto;
import lombok.Getter;
import lombok.Setter;
import java.math.BigDecimal;
import java.util.StringJoiner;
/**
* @author LJF
* @version 1.0
* @project EEMCS
* @description 热水收益总的收益情况
* @date 2026-05-13 09:33:27
*/
@Setter
@Getter
public class HotWaterRevenueSumDTO {
/**
* 时间
*/
private String curDate;
/**
* 建筑id
*/
private String buildingId;
// 电表用量
private BigDecimal totalUseEleAmount;
// 电量单价
private BigDecimal electPrice;
// 用电金额
private BigDecimal totalUseEle;
// 水表用量
private BigDecimal totalUseWaterAmount;
// 水价
private BigDecimal waterPrice;
// 用水金额
private BigDecimal totalUseWater;
// 平均电表用量
private BigDecimal avgUseEle;
// 平均水表用量
private BigDecimal avgUseWater;
// 单耗
private BigDecimal unitConsumption;
// 收益总额
private BigDecimal totalIncome;
@Override
public String toString() {
return new StringJoiner(", ", HotWaterRevenueSumDTO.class.getSimpleName() + "[", "]")
.add("curDate='" + curDate + "'")
.add("buildingId='" + buildingId + "'")
.add("totalUseEleAmount=" + totalUseEleAmount)
.add("electPrice=" + electPrice)
.add("totalUseEle=" + totalUseEle)
.add("totalUseWaterAmount=" + totalUseWaterAmount)
.add("waterPrice=" + waterPrice)
.add("totalUseWater=" + totalUseWater)
.add("avgUseEle=" + avgUseEle)
.add("avgUseWater=" + avgUseWater)
.add("unitConsumption=" + unitConsumption)
.add("totalIncome=" + totalIncome)
.toString();
}
}

284
mh-common/src/main/java/com/mh/common/core/domain/dto/MaglevReportSysParamDTO.java

@ -0,0 +1,284 @@
package com.mh.common.core.domain.dto;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.*;
import com.alibaba.excel.enums.poi.BorderStyleEnum;
import com.alibaba.excel.enums.poi.HorizontalAlignmentEnum;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
//import java.math.String;
/**
* @author LJF
* @version 1.0
* @project NewZhujiang_Server
* @description 磁悬浮主机系统参数报表
* @date 2024-05-30 11:00:12
*/
@Data
@NoArgsConstructor
@Accessors(chain = true)
@HeadRowHeight(25)
@HeadFontStyle(fontHeightInPoints = 14)
@ContentFontStyle(fontHeightInPoints = 13)
@ContentRowHeight(25)
@ContentStyle(
horizontalAlignment = HorizontalAlignmentEnum.CENTER,
borderBottom = BorderStyleEnum.THIN,
borderLeft = BorderStyleEnum.THIN,
borderRight = BorderStyleEnum.THIN,
borderTop = BorderStyleEnum.THIN
)
@ColumnWidth(10)
public class MaglevReportSysParamDTO {
/**
* 当前时间
*/
@ColumnWidth(17)
@ExcelProperty(value = {"${deviceType}", "时间", "时间"}, index = 0)
private String curTime;
// /**
// * 班次
// */
// @ColumnWidth(10)
// @ExcelProperty(value = {"${deviceType}", "班次", "班次"}, index = 1)
// private String classes;
/**
* 冷冻水进水温度
*/
@ColumnWidth(10)
@ExcelProperty(value = {"${deviceType}", "蒸发器", "冷冻水进水温度℃"}, index = 1)
private BigDecimal tempInChillerWater;
/**
* 冷冻水出水温度
*/
@ExcelProperty(value = {"${deviceType}", "蒸发器", "冷冻水出水温度℃"}, index = 2)
@ColumnWidth(10)
private BigDecimal tempOutChillerWater;
/**
* 设计流量%
*/
@ExcelProperty(value = {"${deviceType}", "蒸发器", "设计流量%"}, index = 3)
@ColumnWidth(10)
private BigDecimal designFlow;
/**
* 蒸发器压力kpa
*/
@ExcelProperty(value = {"${deviceType}", "蒸发器", "蒸发器压力kpa"}, index = 4)
@ColumnWidth(10)
private BigDecimal pressEvapSaturation;
/**
* 蒸发器饱和温度
*/
@ExcelProperty(value = {"${deviceType}", "蒸发器", "蒸发器饱和温度℃"}, index = 5)
@ColumnWidth(10)
private BigDecimal tempEvapSaturation;
/**
* 趋近温度
*/
@ExcelProperty(value = {"${deviceType}", "蒸发器", "趋近温度℃"}, index = 6)
@ColumnWidth(10)
private BigDecimal tempEvapApproaching;
/**
* 冷却水进水温度
*/
@ExcelProperty(value = {"${deviceType}", "冷凝器", "冷却水进水温度℃"}, index = 7)
@ColumnWidth(10)
private BigDecimal tempInCoolingWater;
/**
* 冷却水出水温度
*/
@ExcelProperty(value = {"${deviceType}", "冷凝器", "冷却水出水温度℃"}, index = 8)
@ColumnWidth(10)
private BigDecimal tempOutCoolingWater;
/**
* 冷凝器压力kpa
*/
@ExcelProperty(value = {"${deviceType}", "冷凝器", "冷凝器压力kpa"}, index = 9)
@ColumnWidth(10)
private BigDecimal pressCondenserSaturation;
/**
* 冷凝器饱和温度
*/
@ExcelProperty(value = {"${deviceType}", "冷凝器", "冷凝器饱和温度℃"}, index = 10)
@ColumnWidth(10)
private BigDecimal tempCondenserSaturation;
/**
* 冷凝器趋近温度
*/
@ExcelProperty(value = {"${deviceType}", "冷凝器", "趋近温度℃"}, index = 11)
@ColumnWidth(10)
private BigDecimal tempCondenserApproaching;
/**
* 冷冻水设定值
*/
@ExcelProperty(value = {"${deviceType}", "系统", "冷冻水设定值℃"}, index = 12)
@ColumnWidth(10)
private BigDecimal setChillerWater;
/**
* 冷水机需求%
*/
@ExcelProperty(value = {"${deviceType}", "系统", "冷水机需求%"}, index = 13)
@ColumnWidth(10)
private BigDecimal setLoad;
/**
* 总电流A
*/
@ExcelProperty(value = {"${deviceType}", "系统", "总电流A"}, index = 14)
@ColumnWidth(10)
private BigDecimal currentTotal;
/**
* 总输入功率kw
*/
@ExcelProperty(value = {"${deviceType}", "系统", "总输入功率kw"}, index = 15)
@ColumnWidth(10)
private BigDecimal inputPowerTotal;
/**
* 压缩比
*/
// @ExcelProperty(value = {"${deviceType}", "系统", "压缩比"}, index = 16)
// @ColumnWidth(10)
// private BigDecimal ratioComp;
/**
* 压缩比1
*/
@ExcelProperty(value = {"${deviceType}", "系统", "1#压缩机压缩比"}, index = 16)
@ColumnWidth(10)
private BigDecimal ratioCompOne;
/**
* 压缩比2
*/
@ExcelProperty(value = {"${deviceType}", "系统", "2#压缩机压缩比"}, index = 17)
@ColumnWidth(10)
private BigDecimal ratioCompTwo;
/**
* 压缩比3
*/
@ExcelProperty(value = {"${deviceType}", "系统", "3#压缩机压缩比"}, index = 18)
@ColumnWidth(10)
private BigDecimal ratioCompThree;
/**
* 膨胀阀开度%
*/
@ExcelProperty(value = {"${deviceType}", "系统", "膨胀阀开度%"}, index = 19)
@ColumnWidth(10)
private BigDecimal openExv;
/**
* 运行中的压缩机数量
*/
@ExcelProperty(value = {"${deviceType}", "系统", "运行中的压缩机数量"}, index = 20)
@ColumnWidth(10)
private Integer runCompNum;
/**
* 冷冻水泵频率hz
*/
@ExcelProperty(value = {"${deviceType}", "冷冻泵", "冷冻水泵频率hz"}, index = 21)
@ColumnWidth(10)
private BigDecimal frequencyChiller;
/**
* 冷冻水进水压力kpa
*/
@ExcelProperty(value = {"${deviceType}", "冷冻泵", "冷冻水进水压力kpa"}, index = 22)
@ColumnWidth(10)
private BigDecimal pressInChillerWater;
/**
* 冷冻水出水压力kpa
*/
@ExcelProperty(value = {"${deviceType}", "冷冻泵", "冷冻水出水压力kpa"}, index = 23)
@ColumnWidth(10)
private BigDecimal pressOutChillerWater;
/**
* 冷却水泵频率hz
*/
@ExcelProperty(value = {"${deviceType}", "冷却泵", "冷却水泵频率hz"}, index = 24)
@ColumnWidth(10)
private BigDecimal frequencyCooling;
/**
* 冷却水进水压力kpa
*/
@ExcelProperty(value = {"${deviceType}", "冷却泵", "冷却水进水压力kpa"}, index = 25)
@ColumnWidth(10)
private BigDecimal pressInCoolingWater;
/**
* 冷却水出水压力kpa
*/
@ExcelProperty(value = {"${deviceType}", "冷却泵", "冷却水出水压力kpa"}, index = 26)
@ColumnWidth(10)
private BigDecimal pressOutCoolingWater;
/**
* 冷却塔频率hz
*/
@ExcelProperty(value = {"${deviceType}", "冷却塔", "冷却塔频率hz"}, index = 27)
private BigDecimal frequencyCoolingTower;
/**
* 冷却塔运行数量原注释可能有误根据列名调整
*/
@ExcelProperty(value = {"${deviceType}", "冷却塔", "冷却塔运行数量"}, index = 28)
private Integer runCoolingTower;
/**
* 室外温度
*/
@ExcelProperty(value = {"${deviceType}", "室外温度℃", "室外温度℃"}, index = 29)
@ColumnWidth(10)
private BigDecimal tempOutdoor;
/**
* 室外湿度%
*/
@ExcelProperty(value = {"${deviceType}", "室外湿度%", "室外湿度%"}, index = 30)
@ColumnWidth(10)
private BigDecimal humidityOutdoor;
/**
* 恒压补水罐压力
*/
@ExcelProperty(value = {"${deviceType}", "恒压补水罐压力MPa", "恒压补水罐压力MPa"}, index = 31)
@ColumnWidth(10)
private BigDecimal pressConstantWaterTank;
/**
* 巡查记录人
*/
@ExcelProperty(value = {"${deviceType}", "巡查记录人", "巡查记录人"}, index = 32)
@ColumnWidth(20)
private String recorder;
}

179
mh-common/src/main/java/com/mh/common/core/domain/dto/ReportHeatingRunParamDTO.java

@ -0,0 +1,179 @@
package com.mh.common.core.domain.dto;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.*;
import com.alibaba.excel.enums.poi.BorderStyleEnum;
import com.alibaba.excel.enums.poi.HorizontalAlignmentEnum;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
/**
* @author LJF
* @version 1.0
* @project NewZhujiang_Server
* @description 采暖系统参数报表
* @date 2024-05-30 11:00:12
*/
@Data
@NoArgsConstructor
@Accessors(chain = true)
@HeadRowHeight(25)
@HeadFontStyle(fontHeightInPoints = 14)
@ContentFontStyle(fontHeightInPoints = 13)
@ContentRowHeight(20)
@ContentStyle(
horizontalAlignment = HorizontalAlignmentEnum.CENTER,
borderBottom = BorderStyleEnum.THIN,
borderLeft = BorderStyleEnum.THIN,
borderRight = BorderStyleEnum.THIN,
borderTop = BorderStyleEnum.THIN
)
@ColumnWidth(10)
public class ReportHeatingRunParamDTO {
/**
* 当前时间
*/
@ColumnWidth(17)
@ExcelProperty(value = {"${deviceType}", "时间"}, index = 0)
private String curTime;
/**
* 当前状态
*/
@ColumnWidth(10)
@ExcelProperty(value = {"${deviceType}", "1号采暖设备", "运行状态"}, index = 1)
private String runStatusBoilerOne;
/**
* 设定温度
*/
@ExcelProperty(value = {"${deviceType}", "1号采暖设备", "设定温度(℃)"}, index = 2)
@ColumnWidth(10)
private BigDecimal tempSetBoilerOne;
/**
* 出水温度
*/
@ExcelProperty(value = {"${deviceType}", "1号采暖设备", "出水温度(℃)"}, index = 3)
@ColumnWidth(10)
private BigDecimal tempOutBoilerOne;
/**
* 回水温度
*/
@ExcelProperty(value = {"${deviceType}", "1号采暖设备", "回水温度(℃)"}, index = 4)
@ColumnWidth(10)
private BigDecimal tempInBoilerOne;
/**
* 炉水温度
*/
@ExcelProperty(value = {"${deviceType}", "1号采暖设备", "炉水温度(℃)"}, index = 5)
@ColumnWidth(10)
private BigDecimal tempWaterBoilerOne;
/**
* 烟道温度
*/
@ExcelProperty(value = {"${deviceType}", "1号采暖设备", "烟道温度(℃)"}, index = 6)
@ColumnWidth(10)
private BigDecimal tempFlueGasBoilerOne;
/**
* 当前状态
*/
@ColumnWidth(10)
@ExcelProperty(value = {"${deviceType}", "2号采暖设备", "运行状态"}, index = 7)
private String runStatusBoilerTwo;
/**
* 设定温度
*/
@ExcelProperty(value = {"${deviceType}", "2号采暖设备", "设定温度(℃)"}, index = 8)
@ColumnWidth(10)
private BigDecimal tempSetBoilerTwo;
/**
* 出水温度
*/
@ExcelProperty(value = {"${deviceType}", "2号采暖设备", "出水温度(℃)"}, index = 9)
@ColumnWidth(10)
private BigDecimal tempOutBoilerTwo;
/**
* 回水温度
*/
@ExcelProperty(value = {"${deviceType}", "2号采暖设备", "回水温度(℃)"}, index = 10)
@ColumnWidth(10)
private BigDecimal tempInBoilerTwo;
/**
* 炉水温度
*/
@ExcelProperty(value = {"${deviceType}", "2号采暖设备", "炉水温度(℃)"}, index = 11)
@ColumnWidth(10)
private BigDecimal tempWaterBoilerTwo;
/**
* 烟道温度
*/
@ExcelProperty(value = {"${deviceType}", "2号采暖设备", "烟道温度(℃)"}, index = 12)
@ColumnWidth(10)
private BigDecimal tempFlueGasBoilerTwo;
/**
* 当前状态
*/
@ColumnWidth(10)
@ExcelProperty(value = {"${deviceType}", "1号采暖泵", "运行状态"}, index = 13)
private String runStatusPumpOne;
/**
* 频率
*/
@ColumnWidth(10)
@ExcelProperty(value = {"${deviceType}", "1号采暖泵", "频率(Hz)"}, index = 14)
private BigDecimal frequencyPumpOne;
/**
* 当前状态
*/
@ColumnWidth(10)
@ExcelProperty(value = {"${deviceType}", "2号采暖泵", "运行状态"}, index = 15)
private String runStatusPumpTwo;
/**
* 频率
*/
@ColumnWidth(10)
@ExcelProperty(value = {"${deviceType}", "2号采暖泵", "频率(Hz)"}, index = 16)
private BigDecimal frequencyPumpTwo;
/**
* 当前状态
*/
@ColumnWidth(10)
@ExcelProperty(value = {"${deviceType}", "3号采暖泵", "运行状态"}, index = 17)
private String runStatusPumpThree;
/**
* 频率
*/
@ColumnWidth(10)
@ExcelProperty(value = {"${deviceType}", "3号采暖泵", "频率(Hz)"}, index = 18)
private BigDecimal frequencyPumpThree;
// 巡查记录人
@ExcelProperty(value = {"${deviceType}", "巡查记录人", "巡查记录人"}, index = 19)
@ColumnWidth(20)
private String recorder;
// 备注信息
@ExcelProperty(value = {"${deviceType}", "备注", "备注"}, index = 20)
@ColumnWidth(20)
private String remark;
}

135
mh-common/src/main/java/com/mh/common/core/domain/dto/ReportSteamRunParamDTO.java

@ -0,0 +1,135 @@
package com.mh.common.core.domain.dto;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.*;
import com.alibaba.excel.enums.poi.BorderStyleEnum;
import com.alibaba.excel.enums.poi.HorizontalAlignmentEnum;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
/**
* @author LJF
* @version 1.0
* @project NewZhujiang_Server
* @description 蒸汽机系统参数报表
* @date 2024-05-30 11:00:12
*/
@Data
@NoArgsConstructor
@Accessors(chain = true)
@HeadRowHeight(25)
@HeadFontStyle(fontHeightInPoints = 14)
@ContentFontStyle(fontHeightInPoints = 13)
@ContentRowHeight(20)
@ContentStyle(
horizontalAlignment = HorizontalAlignmentEnum.CENTER,
borderBottom = BorderStyleEnum.THIN,
borderLeft = BorderStyleEnum.THIN,
borderRight = BorderStyleEnum.THIN,
borderTop = BorderStyleEnum.THIN
)
@ColumnWidth(10)
public class ReportSteamRunParamDTO {
/**
* 当前时间
*/
@ColumnWidth(17)
@ExcelProperty(value = {"${deviceType}", "时间"}, index = 0)
private String curTime;
/**
* 当前状态
*/
@ColumnWidth(10)
@ExcelProperty(value = {"${deviceType}", "当前状态", "当前状态"}, index = 1)
private String curStatus;
/**
* 火焰强度
*/
@ExcelProperty(value = {"${deviceType}", "火焰强度", "火焰强度"}, index = 2)
@ColumnWidth(10)
private BigDecimal flameIntensity;
/**
* 烟气温度
*/
@ExcelProperty(value = {"${deviceType}", "烟气温度(℃)", "烟气温度(℃)"}, index = 3)
@ColumnWidth(10)
private BigDecimal tempFlueGas;
/**
* 火焰百分比%
*/
@ExcelProperty(value = {"${deviceType}", "火焰百分比(%)", "火焰百分比(%)"}, index = 4)
@ColumnWidth(10)
private BigDecimal percentFlameIntensity;
/**
* 液位%
*/
@ColumnWidth(10)
@ExcelProperty(value = {"${deviceType}", "液位(%)", "液位(%)"}, index = 5)
private BigDecimal waterLevel;
/**
* 蒸汽温度
*/
@ExcelProperty(value = {"${deviceType}", "蒸汽温度(℃)", "蒸汽温度(℃)"}, index = 6)
@ColumnWidth(10)
private BigDecimal tempCur;
/**
* 当前压力Mpa
*/
@ExcelProperty(value = {"${deviceType}", "当前压力(Mpa)", "当前压力(Mpa)"}, index = 7)
@ColumnWidth(10)
private BigDecimal pressCur;
/**
* 压力设定值Mpa
*/
@ExcelProperty(value = {"${deviceType}", "压力设定值(Mpa)", "压力设定值(Mpa)"}, index = 8)
@ColumnWidth(10)
private BigDecimal pressSet;
// 启动压差(Mpa)
@ExcelProperty(value = {"${deviceType}", "启动压差(Mpa)", "启动压差(Mpa)"}, index = 9)
@ColumnWidth(10)
private BigDecimal pressStartDiff;
// 停止压差(Mpa)
@ExcelProperty(value = {"${deviceType}", "停止压差(Mpa)", "停止压差(Mpa)"}, index = 10)
@ColumnWidth(10)
private BigDecimal pressShutdownDiff;
// 瞬时压力(Mpa)
@ExcelProperty(value = {"${deviceType}", "瞬时压力(Mpa)", "瞬时压力(Mpa)"}, index = 11)
@ColumnWidth(10)
private BigDecimal pressInstance;
// 瞬时流量(t/h)
@ExcelProperty(value = {"${deviceType}", "瞬时流量(t/h)", "瞬时流量(t/h)"}, index = 12)
@ColumnWidth(10)
private BigDecimal flowInstance;
// 累积流量(t)
@ExcelProperty(value = {"${deviceType}", "累积流量(t)", "累积流量(t)"}, index = 13)
@ColumnWidth(10)
private BigDecimal flowTotal;
// 巡查记录人
@ExcelProperty(value = {"${deviceType}", "巡查记录人", "巡查记录人"}, index = 14)
@ColumnWidth(20)
private String recorder;
// 备注信息
@ExcelProperty(value = {"${deviceType}", "备注", "备注"}, index = 15)
@ColumnWidth(20)
private String remark;
}

172
mh-common/src/main/java/com/mh/common/core/domain/dto/ThreeFloorReportHotWaterDTO.java

@ -107,113 +107,103 @@ public class ThreeFloorReportHotWaterDTO {
@ColumnWidth(10) @ColumnWidth(10)
private String statusRunHotPumpTwoStr; private String statusRunHotPumpTwoStr;
// // 3号热泵设定温度(℃) // 3号热泵设定温度(℃)
// @ColumnWidth(10) @ColumnWidth(10)
// @ExcelProperty(value = {"${deviceType}", "3号热泵", "设定温度℃"}, index = 9) @ExcelProperty(value = {"${deviceType}", "3号热泵", "设定温度℃"}, index = 9)
// private BigDecimal tempSetHotPumpThree; private BigDecimal tempSetHotPumpThree;
//
// // 3号热泵实际温度(℃) // 3号热泵实际温度(℃)
// @ExcelProperty(value = {"${deviceType}", "3号热泵", "实际温度℃"}, index = 10) @ExcelProperty(value = {"${deviceType}", "3号热泵", "实际温度℃"}, index = 10)
// @ColumnWidth(10) @ColumnWidth(10)
// private BigDecimal tempRealHotPumpThree; private BigDecimal tempRealHotPumpThree;
//
// // 3号热泵启停状态 // 3号热泵启停状态
// @ExcelProperty(value = {"${deviceType}", "3号热泵", "设备开关机"}, index = 11) @ExcelProperty(value = {"${deviceType}", "3号热泵", "设备开关机"}, index = 11)
// @ColumnWidth(10) @ColumnWidth(10)
// private String statusSwitchHotPumpThreeStr; private String statusSwitchHotPumpThreeStr;
//
// // 3号热泵运行状态 // 3号热泵运行状态
// @ExcelProperty(value = {"${deviceType}", "3号热泵", "设备运行状态"}, index = 12) @ExcelProperty(value = {"${deviceType}", "3号热泵", "设备运行状态"}, index = 12)
// @ColumnWidth(10) @ColumnWidth(10)
// private String statusRunHotPumpThreeStr; private String statusRunHotPumpThreeStr;
//
// // 4号热泵设定温度(℃) // 4号热泵设定温度(℃)
// @ColumnWidth(10) @ColumnWidth(10)
// @ExcelProperty(value = {"${deviceType}", "4号热泵", "设定温度℃"}, index = 13) @ExcelProperty(value = {"${deviceType}", "4号热泵", "设定温度℃"}, index = 13)
// private BigDecimal tempSetHotPumpFour; private BigDecimal tempSetHotPumpFour;
//
// // 4号热泵实际温度(℃) // 4号热泵实际温度(℃)
// @ExcelProperty(value = {"${deviceType}", "4号热泵", "实际温度℃"}, index = 14) @ExcelProperty(value = {"${deviceType}", "4号热泵", "实际温度℃"}, index = 14)
// @ColumnWidth(10) @ColumnWidth(10)
// private BigDecimal tempRealHotPumpFour; private BigDecimal tempRealHotPumpFour;
//
// // 4号热泵启停状态 // 4号热泵启停状态
// @ExcelProperty(value = {"${deviceType}", "4号热泵", "设备开关机"}, index = 15) @ExcelProperty(value = {"${deviceType}", "4号热泵", "设备开关机"}, index = 15)
// @ColumnWidth(10) @ColumnWidth(10)
// private String statusSwitchHotPumpFourStr; private String statusSwitchHotPumpFourStr;
//
// // 4号热泵运行状态 // 4号热泵运行状态
// @ExcelProperty(value = {"${deviceType}", "4号热泵", "设备运行状态"}, index = 16) @ExcelProperty(value = {"${deviceType}", "4号热泵", "设备运行状态"}, index = 16)
// @ColumnWidth(10) @ColumnWidth(10)
// private String statusRunHotPumpFourStr; private String statusRunHotPumpFourStr;
//
// // 高区/高区设定压力(bar) // 高区/高区设定压力(bar)
// @ExcelProperty(value = {"${deviceType}", "高区变频泵", "设定压力bar"}, index = 17) @ExcelProperty(value = {"${deviceType}", "高区变频泵", "设定压力bar"}, index = 17)
// @ColumnWidth(10) @ColumnWidth(10)
// private BigDecimal presSetSupplyPumpAreaOne; private BigDecimal presSetSupplyPumpAreaOne;
//
// // 高区/高区实际压力(bar) // 高区/高区实际压力(bar)
// @ExcelProperty(value = {"${deviceType}", "高区变频泵", "实际压力bar"}, index = 18) @ExcelProperty(value = {"${deviceType}", "高区变频泵", "实际压力bar"}, index = 18)
// @ColumnWidth(10) @ColumnWidth(10)
// private BigDecimal presRealSupplyPumpAreaOne; private BigDecimal presRealSupplyPumpAreaOne;
//
// // 高区/高区1号泵运行状态 // 高区/高区1号泵运行状态
// @ExcelProperty(value = {"${deviceType}", "高区变频泵", "1号泵运行状态"}, index = 19) @ExcelProperty(value = {"${deviceType}", "高区变频泵", "1号泵运行状态"}, index = 19)
// @ColumnWidth(10) @ColumnWidth(10)
// private String statusRunSupplyPumpOneStr; private String statusRunSupplyPumpOneStr;
//
// // 高区/高区2号泵运行状态 // 高区/高区2号泵运行状态
// @ExcelProperty(value = {"${deviceType}", "高区变频泵", "2号泵运行状态"}, index = 20) @ExcelProperty(value = {"${deviceType}", "高区变频泵", "2号泵运行状态"}, index = 20)
// @ColumnWidth(10) @ColumnWidth(10)
// private String statusRunSupplyPumpTwoStr; private String statusRunSupplyPumpTwoStr;
//
// // 中区/中区设定压力(bar) // 中区/中区设定压力(bar)
// @ExcelProperty(value = {"${deviceType}", "中区变频泵", "设定压力bar"}, index = 21) @ExcelProperty(value = {"${deviceType}", "中区变频泵", "设定压力bar"}, index = 21)
// @ColumnWidth(10) @ColumnWidth(10)
// private BigDecimal presSetSupplyPumpAreaTwo; private BigDecimal presSetSupplyPumpAreaTwo;
//
// // 中区/中区实际压力(bar) // 中区/中区实际压力(bar)
// @ExcelProperty(value = {"${deviceType}", "中区变频泵", "实际压力bar"}, index = 22) @ExcelProperty(value = {"${deviceType}", "中区变频泵", "实际压力bar"}, index = 22)
// @ColumnWidth(10) @ColumnWidth(10)
// private BigDecimal presRealSupplyPumpAreaTwo; private BigDecimal presRealSupplyPumpAreaTwo;
//
// // 中区/中区1号泵运行状态
// @ExcelProperty(value = {"${deviceType}", "中区变频泵", "1号泵运行状态"}, index = 23)
// @ColumnWidth(10)
// private String statusRunSupplyPumpThreeStr;
//
// // 中区/中区2号泵运行状态
// @ExcelProperty(value = {"${deviceType}", "中区变频泵", "2号泵运行状态"}, index = 24)
// @ColumnWidth(10)
// private String statusRunSupplyPumpFourStr;
// 主楼与贵宾楼1号循环泵运行状态 // 中区/中区1号泵运行状态
@ExcelProperty(value = {"${deviceType}", "主楼与贵宾楼循环泵", "1号循环泵运行状态"}, index = 9) @ExcelProperty(value = {"${deviceType}", "中区变频泵", "1号泵运行状态"}, index = 23)
@ColumnWidth(10) @ColumnWidth(10)
private String statusRunCyclePumpOneStr; private String statusRunSupplyPumpThreeStr;
// 主楼与贵宾楼2号循环泵运行状态 // 中区/中区2号泵运行状态
@ExcelProperty(value = {"${deviceType}", "主楼与贵宾楼循环泵", "2号循环泵运行状态"}, index = 10) @ExcelProperty(value = {"${deviceType}", "中区变频泵", "2号泵运行状态"}, index = 24)
@ColumnWidth(10) @ColumnWidth(10)
private String statusRunCyclePumpTwoStr; private String statusRunSupplyPumpFourStr;
// 主楼水箱1 // 高区/高区液位(米)
@ExcelProperty(value = {"${deviceType}", "水箱液位", "水箱1液位(米)"}, index = 11) @ExcelProperty(value = {"${deviceType}", "水箱液位", "高区液位%"}, index = 25)
@ColumnWidth(10) @ColumnWidth(10)
private BigDecimal levelWaterTankOne; private BigDecimal levelWaterTankOne;
// 主楼水箱2 // 中区/中区液位(米)
@ExcelProperty(value = {"${deviceType}", "水箱液位", "水箱2液位(米)"}, index = 12) @ExcelProperty(value = {"${deviceType}", "水箱液位", "中区液位%"}, index = 26)
@ColumnWidth(10) @ColumnWidth(10)
private BigDecimal levelWaterTankTwo; private BigDecimal levelWaterTankTwo;
// 巡查记录人 // 巡查记录人
@ExcelProperty(value = {"${deviceType}", "巡查记录人", "巡查记录人"}, index = 13) @ExcelProperty(value = {"${deviceType}", "巡查记录人", "巡查记录人"}, index = 27)
@ColumnWidth(20) @ColumnWidth(20)
private String recorder; private String recorder;
// 备注信息 // 备注信息
@ExcelProperty(value = {"${deviceType}", "备注", "备注"}, index = 14) @ExcelProperty(value = {"${deviceType}", "备注", "备注"}, index = 28)
@ColumnWidth(20) @ColumnWidth(20)
private String remark; private String remark;

19
mh-common/src/main/java/com/mh/common/core/domain/entity/AlarmRecords.java

@ -86,13 +86,26 @@ public class AlarmRecords implements Serializable {
/** /**
* 是否发送通知 0未发送 1已发送 * 是否发送通知 0未发送 1已发送
*/ */
private Integer isSend; private int isSend;
public Integer getIsSend() { /**
* 推送次数大于3次不再推送
*/
private int sendNum;
public int getSendNum() {
return sendNum;
}
public void setSendNum(int sendNum) {
this.sendNum = sendNum;
}
public int getIsSend() {
return isSend; return isSend;
} }
public void setIsSend(Integer isSend) { public void setIsSend(int isSend) {
this.isSend = isSend; this.isSend = isSend;
} }

1
mh-common/src/main/java/com/mh/common/core/domain/entity/CpmSpaceRelation.java

@ -84,6 +84,7 @@ public class CpmSpaceRelation extends BaseEntity {
public String toString() { public String toString() {
return new ToStringBuilder(this) return new ToStringBuilder(this)
.append("id", id) .append("id", id)
.append("ledgerId", ledgerId)
.append("cpmId", cpmId) .append("cpmId", cpmId)
.append("areaId", areaId) .append("areaId", areaId)
.append("buildingId", buildingId) .append("buildingId", buildingId)

70
mh-common/src/main/java/com/mh/common/core/domain/entity/EnergyBaseSum.java

@ -1,70 +0,0 @@
package com.mh.common.core.domain.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.math.BigDecimal;
/**
* @author LJF
* @version 1.0
* @project EEMCS
* @description 热水Sum基础类
* @date 2026-05-13 09:50:45
*/
@Data
public class EnergyBaseSum {
private String id;
/**
* 时间
*/
private String curDate;
/**
* 建筑id
*/
private String buildingId;
/**
* 补水
*/
private BigDecimal fillWater;
/**
* 补水与昨日比
*/
private String fillWaterP;
/**
* 用水
*/
private BigDecimal waterValue;
/**
* 用水与昨日比
*/
private String waterP;
/**
* 用电量
*/
private BigDecimal electValue;
/**
* 用电与昨日比
*/
private String electP;
/**
* 单耗
*/
private BigDecimal electWater;
/**
* 单耗与昨日比
*/
private String electWaterP;
}

54
mh-common/src/main/java/com/mh/common/core/domain/entity/EnergyDaySum.java

@ -4,7 +4,6 @@ import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -15,12 +14,61 @@ import java.math.BigDecimal;
* @description 热水时间能耗实体类 * @description 热水时间能耗实体类
* @date 2025-06-18 14:28:30 * @date 2025-06-18 14:28:30
*/ */
@EqualsAndHashCode(callSuper = true)
@Data @Data
@TableName("energy_day_sum") @TableName("energy_day_sum")
public class EnergyDaySum extends EnergyBaseSum { public class EnergyDaySum {
@TableId(value = "id", type = IdType.ASSIGN_UUID) @TableId(value = "id", type = IdType.ASSIGN_UUID)
private String id; private String id;
/**
* 时间
*/
private String curDate;
/**
* 建筑id
*/
private String buildingId;
/**
* 补水
*/
private BigDecimal fillWater;
/**
* 补水与昨日比
*/
private String fillWaterP;
/**
* 用水
*/
private BigDecimal waterValue;
/**
* 用水与昨日比
*/
private String waterP;
/**
* 用电量
*/
private BigDecimal electValue;
/**
* 用电与昨日比
*/
private String electP;
/**
* 单耗
*/
private BigDecimal electWater;
/**
* 单耗与昨日比
*/
private String electWaterP;
} }

54
mh-common/src/main/java/com/mh/common/core/domain/entity/EnergyMonthSum.java

@ -4,7 +4,6 @@ import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -15,12 +14,61 @@ import java.math.BigDecimal;
* @description 热水时间能耗实体类 * @description 热水时间能耗实体类
* @date 2025-06-18 14:28:30 * @date 2025-06-18 14:28:30
*/ */
@EqualsAndHashCode(callSuper = true)
@Data @Data
@TableName("energy_month_sum") @TableName("energy_month_sum")
public class EnergyMonthSum extends EnergyBaseSum { public class EnergyMonthSum {
@TableId(value = "id", type = IdType.ASSIGN_UUID) @TableId(value = "id", type = IdType.ASSIGN_UUID)
private String id; private String id;
/**
* 时间
*/
private String curDate;
/**
* 建筑id
*/
private String buildingId;
/**
* 补水
*/
private BigDecimal fillWater;
/**
* 补水与昨日比
*/
private String fillWaterP;
/**
* 用水
*/
private BigDecimal waterValue;
/**
* 用水与昨日比
*/
private String waterP;
/**
* 用电量
*/
private BigDecimal electValue;
/**
* 用电与昨日比
*/
private String electP;
/**
* 单耗
*/
private BigDecimal electWater;
/**
* 单耗与昨日比
*/
private String electWaterP;
} }

54
mh-common/src/main/java/com/mh/common/core/domain/entity/EnergyYearSum.java

@ -4,7 +4,6 @@ import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -15,12 +14,61 @@ import java.math.BigDecimal;
* @description 热水时间能耗实体类 * @description 热水时间能耗实体类
* @date 2025-06-18 14:28:30 * @date 2025-06-18 14:28:30
*/ */
@EqualsAndHashCode(callSuper = true)
@Data @Data
@TableName("energy_month_sum") @TableName("energy_month_sum")
public class EnergyYearSum extends EnergyBaseSum { public class EnergyYearSum {
@TableId(value = "id", type = IdType.ASSIGN_UUID) @TableId(value = "id", type = IdType.ASSIGN_UUID)
private String id; private String id;
/**
* 时间
*/
private String curDate;
/**
* 建筑id
*/
private String buildingId;
/**
* 补水
*/
private BigDecimal fillWater;
/**
* 补水与昨日比
*/
private String fillWaterP;
/**
* 用水
*/
private BigDecimal waterValue;
/**
* 用水与昨日比
*/
private String waterP;
/**
* 用电量
*/
private BigDecimal electValue;
/**
* 用电与昨日比
*/
private String electP;
/**
* 单耗
*/
private BigDecimal electWater;
/**
* 单耗与昨日比
*/
private String electWaterP;
} }

217
mh-common/src/main/java/com/mh/common/core/domain/entity/ReportHeatingRunParamHis.java

@ -0,0 +1,217 @@
package com.mh.common.core.domain.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.mh.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.Map;
import java.util.StringJoiner;
/**
* @author LJF
* @version 1.0
* @project EEMCS
* @description 采暖系统运行记录表
* @date 2025-10-21 10:26:12
*/
@Data
@TableName("report_heating_run_param_his") // 指定数据库表名
public class ReportHeatingRunParamHis extends BaseEntity {
@TableId(value = "id", type = IdType.ASSIGN_UUID)
private String id;
// 日期
@TableField("cur_date") // 字段映射(可选,若字段名与属性名不一致时需指定)
private LocalDate curDate;
// 时间
@TableField("cur_time")
private String curTime; // 字符串类型直接映射
// 班次
@TableField("classes")
private String classes;
// 锅炉1状态
@TableField("cur_status_boiler_one")
private Integer curStatusBoilerOne;
// 锅炉1状态
@TableField(exist = false)
private String runStatusBoilerOne;
// 锅炉1出水温度(℃)
@TableField("temp_out_boiler_one")
private BigDecimal tempOutBoilerOne; // 精度要求高时使用BigDecimal
// 锅炉1设定温度(℃)
@TableField("temp_set_boiler_one")
private BigDecimal tempSetBoilerOne; // 精度要求高时使用BigDecimal
// 锅炉1回水温度(℃)
@TableField("temp_in_boiler_one")
private BigDecimal tempInBoilerOne;
// 锅炉1炉水温度(℃)
@TableField("temp_water_boiler_one")
private BigDecimal tempWaterBoilerOne;
// 锅炉1烟道温度(℃)
@TableField("temp_flue_gas_boiler_one")
private BigDecimal tempFlueGasBoilerOne;
// 锅炉2状态
@TableField("cur_status_boiler_two")
private Integer curStatusBoilerTwo;
// 锅炉2状态
@TableField(exist = false)
private String runStatusBoilerTwo;
// 锅炉2设定温度(℃)
@TableField("temp_set_boiler_two")
private BigDecimal tempSetBoilerTwo; // 精度要求高时使用BigDecimal
// 锅炉2出水温度(℃)
@TableField("temp_out_boiler_two")
private BigDecimal tempOutBoilerTwo;
// 锅炉2回水温度(℃)
@TableField("temp_in_boiler_two")
private BigDecimal tempInBoilerTwo;
// 锅炉2炉水温度(℃)
@TableField("temp_water_boiler_two")
private BigDecimal tempWaterBoilerTwo;
// 锅炉2烟道温度(℃)
@TableField("temp_flue_gas_boiler_two")
private BigDecimal tempFlueGasBoilerTwo;
// 采暖泵1状态
@TableField("cur_status_pump_one")
private Integer curStatusPumpOne;
// 采暖泵1状态
@TableField(exist = false)
private String runStatusPumpOne;
// 采暖泵1频率(Hz)
@TableField("frequency_pump_one")
private BigDecimal frequencyPumpOne;
// 采暖泵2状态
@TableField("cur_status_pump_two")
private Integer curStatusPumpTwo;
// 采暖泵2状态
@TableField(exist = false)
private String runStatusPumpTwo;
// 采暖泵2频率(Hz)
@TableField("frequency_pump_two")
private BigDecimal frequencyPumpTwo;
// 采暖泵3状态
@TableField("cur_status_pump_three")
private Integer curStatusPumpThree;
// 采暖泵3状态
@TableField(exist = false)
private String runStatusPumpThree;
// 采暖泵3频率(Hz)
@TableField("frequency_pump_three")
private BigDecimal frequencyPumpThree;
// 巡查记录人
@TableField("recorder")
private String recorder;
// 备注
@TableField("remark")
private String remark;
// 创建时间(自动填充)
@TableField(value = "create_date", fill = FieldFill.INSERT) // 插入时自动填充
private LocalDateTime createDate;
@JsonIgnore
@TableField(exist = false)
private String searchValue;
/**
* 请求参数
*/
@TableField(exist = false)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private Map<String, Object> params;
/** 创建者 */
@JsonIgnore
@TableField(exist = false)
private String createBy;
/** 创建时间 */
@TableField(exist = false)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/** 更新者 */
@JsonIgnore
@TableField(exist = false)
private String updateBy;
/** 更新时间 */
@JsonIgnore
@TableField(exist = false)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
/** 更新者 */
@TableField(exist = false)
private int pageNum;
/** 更新者 */
@TableField(exist = false)
private int pageSize;
@Override
public String toString() {
return new StringJoiner(", ", ReportHeatingRunParamHis.class.getSimpleName() + "[", "]")
.add("id='" + id + "'")
.add("curDate=" + curDate)
.add("curTime='" + curTime + "'")
.add("classes='" + classes + "'")
.add("curStatusBoilerOne=" + curStatusBoilerOne)
.add("tempOutBoilerOne=" + tempOutBoilerOne)
.add("tempInBoilerOne=" + tempInBoilerOne)
.add("tempWaterBoilerOne=" + tempWaterBoilerOne)
.add("tempFlueGasBoilerOne=" + tempFlueGasBoilerOne)
.add("curStatusBoilerTwo=" + curStatusBoilerTwo)
.add("tempOutBoilerTwo=" + tempOutBoilerTwo)
.add("tempInBoilerTwo=" + tempInBoilerTwo)
.add("tempWaterBoilerTwo=" + tempWaterBoilerTwo)
.add("tempFlueGasBoilerTwo=" + tempFlueGasBoilerTwo)
.add("curStatusPumpOne=" + curStatusPumpOne)
.add("frequencyPumpOne=" + frequencyPumpOne)
.add("curStatusPumpTwo=" + curStatusPumpTwo)
.add("frequencyPumpTwo=" + frequencyPumpTwo)
.add("curStatusPumpThree=" + curStatusPumpThree)
.add("frequencyPumpThree=" + frequencyPumpThree)
.add("recorder='" + recorder + "'")
.add("remark='" + remark + "'")
.add("createDate=" + createDate)
.toString();
}
}

54
mh-common/src/main/java/com/mh/common/core/domain/entity/ReportHotWaterParamHis.java

@ -99,54 +99,6 @@ public class ReportHotWaterParamHis extends BaseEntity implements Serializable {
// 4号热泵运行状态 // 4号热泵运行状态
private Integer statusRunHotPumpFour; private Integer statusRunHotPumpFour;
// 5号热泵设定温度(℃)
private BigDecimal tempSetHotPumpFive;
// 5号热泵实际温度(℃)
private BigDecimal tempRealHotPumpFive;
// 5号热泵启停状态(0-关闭,1-开启)
private Integer statusSwitchHotPumpFive;
// 5号热泵运行状态(0-故障,1-正常)
private Integer statusRunHotPumpFive;
// 6号热泵设定温度(℃)
private BigDecimal tempSetHotPumpSix;
// 6号热泵实际温度(℃)
private BigDecimal tempRealHotPumpSix;
// 6号热泵启停状态
private Integer statusSwitchHotPumpSix;
// 6号热泵运行状态
private Integer statusRunHotPumpSix;
// 7号热泵设定温度(℃)
private BigDecimal tempSetHotPumpSeven;
// 7号热泵实际温度(℃)
private BigDecimal tempRealHotPumpSeven;
// 7号热泵启停状态
private Integer statusSwitchHotPumpSeven;
// 7号热泵运行状态
private Integer statusRunHotPumpSeven;
// 8号热泵设定温度(℃)
private BigDecimal tempSetHotPumpEight;
// 8号热泵实际温度(℃)
private BigDecimal tempRealHotPumpEight;
// 8号热泵启停状态
private Integer statusSwitchHotPumpEight;
// 8号热泵运行状态
private Integer statusRunHotPumpEight;
// 高区/裙楼设定压力(MPa) // 高区/裙楼设定压力(MPa)
private BigDecimal presSetSupplyPumpAreaOne; private BigDecimal presSetSupplyPumpAreaOne;
@ -176,12 +128,6 @@ public class ReportHotWaterParamHis extends BaseEntity implements Serializable {
// 中区/中厨液位(米) // 中区/中厨液位(米)
private BigDecimal levelWaterTankTwo; private BigDecimal levelWaterTankTwo;
// 主楼与贵宾楼循环泵1
private Integer statusRunCyclePumpOne;
// 主楼与贵宾楼循环泵2
private Integer statusRunCyclePumpTwo;
// 巡查记录人 // 巡查记录人
private String recorder; private String recorder;

114
mh-common/src/main/java/com/mh/common/core/domain/entity/ReportMeterReadingsHis.java

@ -0,0 +1,114 @@
package com.mh.common.core.domain.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Getter;
import lombok.Setter;
import java.math.BigDecimal;
import java.util.Date;
import java.util.StringJoiner;
/**
* @author LJF
* @version 1.0
* @project EEMCS
* @description 设备抄表记录表
* @date 2025-10-21 10:26:12
*/
@Setter
@Getter
public class ReportMeterReadingsHis {
@TableId(value = "id", type = IdType.ASSIGN_UUID)
private String id;
/**
* 设备类型
*/
private String mtType;
/**
* 设备位置
*/
private String location;
/**
* 设备编号
*/
private String mtNum;
/**
* 昨日抄表读数
*/
private BigDecimal yesterdayReading;
/**
* 昨日抄表时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date yesterdayTimestamp;
/**
* 当日抄表读数
*/
private BigDecimal todayReading;
/**
* 当日抄表时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date todayTimestamp;
/**
* 设备倍率
*/
private int mtRatio;
/**
* 当日总读数*设备倍率
*/
private BigDecimal total;
/**
* 当日单价
*/
private BigDecimal unitPrice;
/**
* 当日金额
*/
private BigDecimal cost;
/**
* 记录创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/**
* 排序序号
*/
private int sortOrder;
@Override
public String toString() {
return new StringJoiner(", ", ReportMeterReadingsHis.class.getSimpleName() + "[", "]")
.add("id='" + id + "'")
.add("mtType='" + mtType + "'")
.add("location='" + location + "'")
.add("mtNum='" + mtNum + "'")
.add("yesterdayReading=" + yesterdayReading)
.add("yesterdayTimestamp=" + yesterdayTimestamp)
.add("todayReading=" + todayReading)
.add("todayTimestamp=" + todayTimestamp)
.add("mtRatio=" + mtRatio)
.add("total=" + total)
.add("unitPrice=" + unitPrice)
.add("cost=" + cost)
.add("createTime=" + createTime)
.add("sortOrder=" + sortOrder)
.toString();
}
}

170
mh-common/src/main/java/com/mh/common/core/domain/entity/ReportSteamRunParamHis.java

@ -0,0 +1,170 @@
package com.mh.common.core.domain.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.mh.common.core.domain.BaseEntity;
import lombok.Getter;
import lombok.Setter;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Date;
import java.util.Map;
import java.util.StringJoiner;
/**
* @author LJF
* @version 1.0
* @project EEMCS
* @description 生活热水供水热泵运行情况
* @date 2025-10-22 17:40:03
*/
@Setter
@Getter
@TableName("report_steam_run_param_his")
public class ReportSteamRunParamHis extends BaseEntity implements Serializable {
// 主键
@Serial
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Long id;
// 记录日期
private LocalDate curDate;
// 记录时间(varchar格式)
private String curTime;
// 班次
private String classes;
// 蒸汽机状态字
private Integer curStatus;
// 运行状态
// @JsonIgnore
@TableField(exist = false)
private String runStatus;
// 火焰强度
private BigDecimal flameIntensity;
// 烟气温度(℃)
private BigDecimal tempFlueGas;
// 火焰百分比(%)
private BigDecimal percentFlameIntensity;
// 液位(%)
private BigDecimal waterLevel;
// 蒸汽温度(℃)
private BigDecimal tempCur;
// 当前压力(Mpa)
private BigDecimal pressCur;
// 压力设定值(Mpa)
private BigDecimal pressSet;
// 启动压差(Mpa)
private BigDecimal pressStartDiff;
// 停止压差(Mpa)
private BigDecimal pressShutdownDiff;
// 瞬时压力(Mpa)
private BigDecimal pressInstance;
// 瞬时流量(t/h)
private BigDecimal flowInstance;
// 累积流量(t)
private BigDecimal flowTotal;
// 巡查记录人
private String recorder;
// 备注信息
private String remark;
@JsonIgnore
@TableField(exist = false)
private String searchValue;
/**
* 请求参数
*/
@TableField(exist = false)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private Map<String, Object> params;
/** 创建者 */
@JsonIgnore
@TableField(exist = false)
private String createBy;
/** 创建时间 */
@TableField(exist = false)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/** 更新者 */
@JsonIgnore
@TableField(exist = false)
private String updateBy;
/** 更新时间 */
@JsonIgnore
@TableField(exist = false)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
/** 更新者 */
@TableField(exist = false)
private int pageNum;
/** 更新者 */
@TableField(exist = false)
private int pageSize;
@Override
public String toString() {
return new StringJoiner(", ", ReportSteamRunParamHis.class.getSimpleName() + "[", "]")
.add("id='" + id + "'")
.add("curDate=" + curDate)
.add("curTime='" + curTime + "'")
.add("classes='" + classes + "'")
.add("curStatus=" + curStatus)
.add("flameIntensity=" + flameIntensity)
.add("tempFlueGas=" + tempFlueGas)
.add("percentFlameIntensity=" + percentFlameIntensity)
.add("waterLevel=" + waterLevel)
.add("tempCur=" + tempCur)
.add("pressCur=" + pressCur)
.add("pressSet=" + pressSet)
.add("pressStartDiff=" + pressStartDiff)
.add("pressShutdownDiff=" + pressShutdownDiff)
.add("pressInstance=" + pressInstance)
.add("flowInstance=" + flowInstance)
.add("flowTotal=" + flowTotal)
.add("recorder='" + recorder + "'")
.add("remark='" + remark + "'")
.add("searchValue='" + searchValue + "'")
.add("params=" + params)
.add("createBy='" + createBy + "'")
.add("createTime=" + createTime)
.add("updateBy='" + updateBy + "'")
.add("updateTime=" + updateTime)
.toString();
}
}

2
mh-common/src/main/java/com/mh/common/core/domain/entity/SysRole.java

@ -91,7 +91,7 @@ public class SysRole extends BaseEntity
public static boolean isAdmin(Long roleId) public static boolean isAdmin(Long roleId)
{ {
return roleId != null && 1L == roleId; return roleId != null && (1L == roleId || 10005L == roleId);
} }
@NotBlank(message = "角色名称不能为空") @NotBlank(message = "角色名称不能为空")

2
mh-common/src/main/java/com/mh/common/core/domain/entity/SysUser.java

@ -121,7 +121,7 @@ public class SysUser extends BaseEntity
public static boolean isAdmin(Long userId) public static boolean isAdmin(Long userId)
{ {
return userId != null && 1L == userId; return userId != null && (1L == userId || 10005L == userId);
} }
public Long getDeptId() public Long getDeptId()

20
mh-common/src/main/java/com/mh/common/core/domain/entity/WeatherData.java

@ -77,26 +77,6 @@ public class WeatherData {
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createdTime; private Date createdTime;
/**
* 含湿量 g/kg
*/
private Double humidityContent;
/**
* 焓值kJ/kg
*/
private Double enthalpy;
/**
* 露点温度摄氏度
*/
private Double dewPointTemp;
/**
* 湿球温度
*/
private Double wetBulbTemp;
@Override @Override
public String toString() { public String toString() {
return new ToStringBuilder(this) return new ToStringBuilder(this)

53
mh-common/src/main/java/com/mh/common/core/domain/vo/CollectionParamsManageDataVO.java

@ -0,0 +1,53 @@
package com.mh.common.core.domain.vo;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;
/**
* @author LJF
* @version 1.0
* @project EEMCS
* @description 辅助计算类
* @date 2026-01-28 14:27:20
*/
@Data
public class CollectionParamsManageDataVO {
// getter方法
private String deviceName;
private String mtNum;
private Integer orderNum;
private String systemType;
private String deviceType;
private String otherName;
private String paramType;
private BigDecimal curValue;
private Date curTime;
private Integer grade;
private Integer status;
// 构造函数
public CollectionParamsManageDataVO(Map<String, Object> map) {
this.deviceName = (String) map.get("device_name");
this.mtNum = (String) map.get("mt_num");
this.orderNum = map.get("order_num") instanceof Integer ?
(Integer) map.get("order_num") :
(map.get("order_num") != null ? Integer.valueOf(map.get("order_num").toString()) : null);
this.systemType = (String) map.get("system_type");
this.deviceType = (String) map.get("device_type");
this.otherName = (String) map.get("other_name");
this.paramType = (String) map.get("param_type");
this.curValue = map.get("cur_value") instanceof BigDecimal ?
(BigDecimal) map.get("cur_value") :
(map.get("cur_value") != null ? new BigDecimal(map.get("cur_value").toString()) : BigDecimal.ZERO);
this.curTime = (Date) map.get("cur_time");
this.grade = map.get("grade") instanceof Integer ?
(Integer) map.get("grade") :
(map.get("grade") != null ? Integer.valueOf(map.get("grade").toString()) : null);
this.status = (Integer) map.get("status");
}
}

5
mh-common/src/main/java/com/mh/common/core/domain/vo/CollectionParamsManageVO.java

@ -46,6 +46,11 @@ public class CollectionParamsManageVO {
private int mtRatio; private int mtRatio;
/**
* 通信质量
*/
private String quality;
public BigDecimal getCurValue() { public BigDecimal getCurValue() {
return curValue; return curValue;
} }

6
mh-common/src/main/java/com/mh/common/core/domain/vo/DeviceMonitorVO.java

@ -62,7 +62,10 @@ public class DeviceMonitorVO {
private int orderNum; private int orderNum;
private String gatewayId; /**
* 采集值质量
*/
private String quality;
@Override @Override
public String toString() { public String toString() {
@ -76,7 +79,6 @@ public class DeviceMonitorVO {
.append("collectValue", collectValue) .append("collectValue", collectValue)
.append("paramType", paramType) .append("paramType", paramType)
.append("orderNum", orderNum) .append("orderNum", orderNum)
.append("gatewayId", gatewayId)
.toString(); .toString();
} }
} }

14
mh-common/src/main/java/com/mh/common/core/domain/vo/EnergyConsumptionVO.java

@ -45,6 +45,20 @@ public class EnergyConsumptionVO implements Serializable {
*/ */
private String systemType; private String systemType;
/**
* 房间id
* @return
*/
private String houseId;
public String getHouseId() {
return houseId;
}
public void setHouseId(String houseId) {
this.houseId = houseId;
}
public String getSystemType() { public String getSystemType() {
return systemType; return systemType;
} }

67
mh-common/src/main/java/com/mh/common/core/domain/vo/HotWaterControlVO.java

@ -62,21 +62,6 @@ public class HotWaterControlVO {
private BigDecimal waterLevelSet; private BigDecimal waterLevelSet;
private String waterLevelSetId; private String waterLevelSetId;
// 水位设置 10
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "0.0")
private BigDecimal waterLevelSet1;
private String waterLevelSetId1;
// 水位误差设置 46
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "0.0")
private BigDecimal waterLevelErrorSet;
private String waterLevelErrorSetId;
// 水位误差设置 46
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "0.0")
private BigDecimal waterLevelErrorSet1;
private String waterLevelErrorSetId1;
// 水位 11 // 水位 11
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "0.0") @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "0.0")
private BigDecimal waterLevel; private BigDecimal waterLevel;
@ -131,65 +116,15 @@ public class HotWaterControlVO {
private String emergencyStopStatusId; private String emergencyStopStatusId;
// 最低设置值 44 // 最低设置值 44
private BigDecimal minSet; private int minSet;
private String minSetId; private String minSetId;
// 设定值上限
private BigDecimal maxValueSet;
private String maxValueSetId;
// 设定值下限
private BigDecimal minValueSet;
private String minValueSetId;
// 校准值
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "0")
private BigDecimal calibrationValue;
private String calibrationValueId;
// 工程量最低值
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "0")
private BigDecimal engineeringMinValue;
private String engineeringMinValueId;
// 工程量最高值
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "0")
private BigDecimal engineeringMaxValue;
private String engineeringMaxValueId;
// 数字量最低值
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "0")
private BigDecimal digitalMinValue;
private String digitalMinValueId;
// 数字量最高值
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "0")
private BigDecimal digitalMaxValue;
private String digitalMaxValueId;
// 中间值
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "0")
private BigDecimal middleValue;
private String middleValueId;
// 累积运行时长:小时单位
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "0")
private BigDecimal runningTime;
private String runningTimeId;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date curTime; private Date curTime;
// 异常复位:45
private int exceptionReset;
private String exceptionResetId;
private int orderNum; private int orderNum;
// 本地远程状态 22: 0-本地 1-远程
private int localRemoteStatus;
private String localRemoteStatusId;
public void setCounterSet(BigDecimal counterSet) { public void setCounterSet(BigDecimal counterSet) {
if (counterSet != null) { if (counterSet != null) {
counterSet = counterSet.setScale(0, BigDecimal.ROUND_HALF_UP); counterSet = counterSet.setScale(0, BigDecimal.ROUND_HALF_UP);

7
mh-common/src/main/java/com/mh/common/model/request/AdvantechDatas.java

@ -27,4 +27,11 @@ public class AdvantechDatas<T extends Number> {
*/ */
private T quality; private T quality;
public AdvantechDatas() {}
public AdvantechDatas(String tag, T value) {
this.tag = tag;
this.value = value;
}
} }

74
mh-common/src/main/java/com/mh/common/model/request/AdvantechJsonParser.java

@ -0,0 +1,74 @@
package com.mh.common.model.request;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @author LJF
* @version 1.0
* @project EEMCS
* @description 昆仑通态触摸屏数据转换
* @date 2026-02-02 15:29:47
*/
public class AdvantechJsonParser {
/**
* 将JSON字符串解析为 AdvantechReceiver<AdvantechDatas<Number>>
* @param json 原始MQTT JSON
* @param defaultQuality quality默认值如192表示Good传null则不设置
* @return 解析后的接收对象
*/
public static AdvantechReceiver<AdvantechDatas<Number>> parse(
String json,
Number defaultQuality) {
JSONObject root = JSON.parseObject(json);
AdvantechReceiver<AdvantechDatas<Number>> receiver = new AdvantechReceiver<>();
// 1. 提取ts(保留原始字符串格式)
// "2026-02-02T18:33:57.712049"时间格式是这个,转成yyyy-MM-dd HH:mm:ss
root.put("ts", root.getString("ts").replace("T", " ").substring(0, 19));
receiver.setTs(root.getString("ts"));
// 2. 解析d数组:展开所有键值对 → AdvantechDatas
List<AdvantechDatas<Number>> dataList = new ArrayList<>();
JSONArray dArray = root.getJSONArray("d");
if (dArray != null) {
for (int i = 0; i < dArray.size(); i++) {
JSONObject item = dArray.getJSONObject(i);
if (item == null || item.isEmpty()) continue;
for (Map.Entry<String, Object> entry : item.entrySet()) {
String tag = entry.getKey();
Object val = entry.getValue();
if (val instanceof Number) {
AdvantechDatas<Number> data = new AdvantechDatas<>();
data.setTag(tag);
data.setValue((Number) val);
if (defaultQuality != null) {
data.setQuality(defaultQuality);
}
dataList.add(data);
}
// 非数值字段自动跳过(可扩展日志)
}
}
}
receiver.setD(dataList);
return receiver;
}
// 便捷重载:不设置quality
public static AdvantechReceiver<AdvantechDatas<Number>> parse(String json) {
return parse(json, 0);
}
}

39
mh-common/src/main/java/com/mh/common/model/response/ParseResult.java

@ -1,39 +0,0 @@
package com.mh.common.model.response;
import lombok.Data;
import java.math.BigDecimal;
/**
* @author LJF
* @version 1.0
* @project EEMCS
* @description 定义统一的数据解析结果对象
* @date 2026-04-28 11:41:34
*/
@Data
public class ParseResult {
private boolean success;
private BigDecimal value;
private String tagName;
private int quality;
private String errorMessage;
public static ParseResult success(BigDecimal value, String tagName) {
ParseResult result = new ParseResult();
result.setSuccess(true);
result.setValue(value);
result.setTagName(tagName);
result.setQuality(0);
return result;
}
public static ParseResult fail(String errorMessage) {
ParseResult result = new ParseResult();
result.setSuccess(false);
result.setErrorMessage(errorMessage);
return result;
}
}

138
mh-common/src/main/java/com/mh/common/utils/AnalysisReceiveOrder485.java

@ -59,16 +59,16 @@ public class AnalysisReceiveOrder485 {
try { try {
if (registerAddr.equals("32") || registerAddr.equals("33") || registerAddr.equals("35") || registerAddr.equals("36")) { if (registerAddr.equals("32") || registerAddr.equals("33") || registerAddr.equals("35") || registerAddr.equals("36")) {
data = decimalFormat.format(Math.abs(ExchangeStringUtil.hexToSingle(data)));//十六进制字符串转IEEE754浮点型 data = decimalFormat.format(Math.abs(ExchangeStringUtil.hexToSingle(data)));//十六进制字符串转IEEE754浮点型
// log.info("冷量计==>{},寄存器地址==>{},读数==>{}", cloudId, registerAddr, data); log.info("冷量计==>{},寄存器地址==>{},读数==>{}", cloudId, registerAddr, data);
} else if (registerAddr.equals("31") || registerAddr.equals("34")) { } else if (registerAddr.equals("31") || registerAddr.equals("34")) {
long lData = Long.parseLong(ExchangeStringUtil.hexToDec(data)); long lData = Long.parseLong(ExchangeStringUtil.hexToDec(data));
// log.info("冷量计==>{},寄存器地址==>{},累计读数==>{}", cloudId, registerAddr, lData); log.info("冷量计==>{},寄存器地址==>{},累计读数==>{}", cloudId, registerAddr, lData);
} }
} catch (Exception e) { } catch (Exception e) {
log.error("保存冷量计数据失败!", e); log.error("保存冷量计数据失败!", e);
} }
} else { } else {
// log.info("冷量计校验失败===>{}", dataStr); log.info("冷量计校验失败===>{}", dataStr);
} }
} }
@ -113,7 +113,7 @@ public class AnalysisReceiveOrder485 {
try { try {
if (dataType == 3) { if (dataType == 3) {
data = decimalFormat.format(Math.abs(ExchangeStringUtil.hexToSingle(data)));//十六进制字符串转IEEE754浮点型 data = decimalFormat.format(Math.abs(ExchangeStringUtil.hexToSingle(data)));//十六进制字符串转IEEE754浮点型
// log.info("水表==>{},寄存器地址==>{},读数==>{}", cloudId, deviceCodeParam.getRegisterAddr(), data); log.info("水表==>{},寄存器地址==>{},读数==>{}", cloudId, deviceCodeParam.getRegisterAddr(), data);
} else if (dataType == 2) { } else if (dataType == 2) {
data = dataStr.substring(dataStr.length() - 12, dataStr.length() - 10) data = dataStr.substring(dataStr.length() - 12, dataStr.length() - 10)
+ dataStr.substring(dataStr.length() - 10, dataStr.length() - 8) + dataStr.substring(dataStr.length() - 10, dataStr.length() - 8)
@ -123,7 +123,7 @@ public class AnalysisReceiveOrder485 {
BigDecimal bigDecimal = new BigDecimal(data); BigDecimal bigDecimal = new BigDecimal(data);
bigDecimal = bigDecimal.divide(new BigDecimal((int) Math.pow(10, deviceCodeParam.getDigits()))).setScale(2, RoundingMode.HALF_UP); // 除以1000并保留整数 bigDecimal = bigDecimal.divide(new BigDecimal((int) Math.pow(10, deviceCodeParam.getDigits()))).setScale(2, RoundingMode.HALF_UP); // 除以1000并保留整数
data = bigDecimal.toString(); data = bigDecimal.toString();
// log.info("水表==>{},寄存器地址==>{},累计读数==>{}", cloudId, deviceCodeParam.getRegisterAddr(), data); log.info("水表==>{},寄存器地址==>{},累计读数==>{}", cloudId, deviceCodeParam.getRegisterAddr(), data);
} }
// 判断data大于99999999,就返回空 // 判断data大于99999999,就返回空
if (new BigDecimal(data).intValue() > 99999999) { if (new BigDecimal(data).intValue() > 99999999) {
@ -134,7 +134,7 @@ public class AnalysisReceiveOrder485 {
log.error("保存水表数据失败!", e); log.error("保存水表数据失败!", e);
} }
} else { } else {
// log.info("水表===>{}", dataStr); log.info("水表===>{}", dataStr);
return ""; return "";
} }
return ""; return "";
@ -165,7 +165,7 @@ public class AnalysisReceiveOrder485 {
DecimalFormat decimalFormat = new DecimalFormat("0.00"); DecimalFormat decimalFormat = new DecimalFormat("0.00");
// 表号 // 表号
String cloudId = ExchangeStringUtil.hexToDec(dataStr.substring(0, 2)); String cloudId = ExchangeStringUtil.hexToDec(dataStr.substring(0, 2));
// 读数 02 04 04 00 04 4D 1F FD DD // 读数
String data = ""; String data = "";
data = dataStr.substring(dataStr.length() - 8, dataStr.length() - 6) data = dataStr.substring(dataStr.length() - 8, dataStr.length() - 6)
+ dataStr.substring(dataStr.length() - 6, dataStr.length() - 4) + dataStr.substring(dataStr.length() - 6, dataStr.length() - 4)
@ -183,20 +183,10 @@ public class AnalysisReceiveOrder485 {
try { try {
if (dataType == 3) { if (dataType == 3) {
data = decimalFormat.format(Math.abs(ExchangeStringUtil.hexToSingle(data)));//十六进制字符串转IEEE754浮点型 data = decimalFormat.format(Math.abs(ExchangeStringUtil.hexToSingle(data)));//十六进制字符串转IEEE754浮点型
// log.info("电表==>{},寄存器地址==>{},读数==>{}", cloudId, deviceCodeParam.getRegisterAddr(), data); log.info("电表==>{},寄存器地址==>{},读数==>{}", cloudId, deviceCodeParam.getRegisterAddr(), data);
} else if (dataType == 2) { } else if (dataType == 2) {
data = ExchangeStringUtil.hexToDec(data); data = ExchangeStringUtil.hexToDec(data);
// log.info("电表==>{},寄存器地址==>{},累计读数==>{}", cloudId, deviceCodeParam.getRegisterAddr(), data); log.info("电表==>{},寄存器地址==>{},累计读数==>{}", cloudId, deviceCodeParam.getRegisterAddr(), data);
} else if (dataType == 4) {
data = dataStr.substring(dataStr.length() - 12, dataStr.length() - 10)
+ dataStr.substring(dataStr.length() - 10, dataStr.length() - 8)
+ dataStr.substring(dataStr.length() - 8, dataStr.length() - 6)
+ dataStr.substring(dataStr.length() - 6, dataStr.length() - 4);
data = ExchangeStringUtil.hexToDec(data);
BigDecimal bigDecimal = new BigDecimal(data);
bigDecimal = bigDecimal.divide(new BigDecimal((int) Math.pow(10, deviceCodeParam.getDigits()))).setScale(2, RoundingMode.HALF_UP); // 除以1000并保留整数
data = bigDecimal.toString();
// log.info("电表==>{},寄存器地址==>{},累计读数==>{}", cloudId, deviceCodeParam.getRegisterAddr(), data);
} }
// 判断data大于99999999,就返回空 // 判断data大于99999999,就返回空
if (new BigDecimal(data).intValue() > 99999999) { if (new BigDecimal(data).intValue() > 99999999) {
@ -207,7 +197,7 @@ public class AnalysisReceiveOrder485 {
log.error("保存电表数据失败!", e); log.error("保存电表数据失败!", e);
} }
} else { } else {
// log.info("电表===>{}", dataStr); log.info("电表===>{}", dataStr);
return ""; return "";
} }
return ""; return "";
@ -280,13 +270,13 @@ public class AnalysisReceiveOrder485 {
)) { )) {
data = ExchangeStringUtil.hexToDec(data); data = ExchangeStringUtil.hexToDec(data);
} }
// log.info("热泵==>{},寄存器地址==>{},读数==>{}", cloudId, deviceCodeParam.getRegisterAddr(), data); log.info("热泵==>{},寄存器地址==>{},读数==>{}", cloudId, deviceCodeParam.getRegisterAddr(), data);
return data; return data;
} catch (Exception e) { } catch (Exception e) {
log.error("保存热泵数据失败!", e); log.error("保存热泵数据失败!", e);
} }
} else { } else {
// log.info("热泵===>{}", dataStr); log.info("热泵===>{}", dataStr);
return ""; return "";
} }
return ""; return "";
@ -327,7 +317,7 @@ public class AnalysisReceiveOrder485 {
BigDecimal bigDecimal = new BigDecimal(data); BigDecimal bigDecimal = new BigDecimal(data);
bigDecimal = bigDecimal.divide(new BigDecimal((int) Math.pow(10, deviceCodeParam.getDigits()))).setScale(3, RoundingMode.HALF_UP); // 除以1000并保留整数 bigDecimal = bigDecimal.divide(new BigDecimal((int) Math.pow(10, deviceCodeParam.getDigits()))).setScale(3, RoundingMode.HALF_UP); // 除以1000并保留整数
data = bigDecimal.toString(); data = bigDecimal.toString();
// log.info("液位==>{},寄存器地址==>{},实时读数==>{}", cloudId, deviceCodeParam.getRegisterAddr(), data); log.info("液位==>{},寄存器地址==>{},实时读数==>{}", cloudId, deviceCodeParam.getRegisterAddr(), data);
} }
// 判断data大于99999999,就返回空 // 判断data大于99999999,就返回空
if (new BigDecimal(data).intValue() > 100) { if (new BigDecimal(data).intValue() > 100) {
@ -338,109 +328,9 @@ public class AnalysisReceiveOrder485 {
log.error("保存液位数据失败!", e); log.error("保存液位数据失败!", e);
} }
} else { } else {
// log.info("液位===>{}", dataStr); log.info("液位===>{}", dataStr);
return "";
}
return "";
}
public String analysisTempHumiditySensorOrder485(String receiveStr, CollectionParamsManage deviceCodeParam) {
// 去掉空格
String dataStr = receiveStr.replace(" ", "").toUpperCase();
// 检验报文
String checkStr = dataStr.substring(0, dataStr.length() - 4);
byte[] strOrder = ExchangeStringUtil.hexStrToBinaryStr(checkStr);
int checkNum = CRC16.CRC16_MODBUS(strOrder);
String checkWord = ExchangeStringUtil.decToHex(String.valueOf(checkNum));
checkWord = checkWord.substring(2, 4) + checkWord.substring(0, 2);
if (checkWord.equalsIgnoreCase(dataStr.substring(dataStr.length() - 4))) {
// 表号
String cloudId = ExchangeStringUtil.hexToDec(dataStr.substring(0, 2));
// 读数
String data = "";
data = dataStr.substring(dataStr.length() - 8, dataStr.length() - 4);
int dataType = deviceCodeParam.getDataType();
try {
if (dataType == 2) {
data = ExchangeStringUtil.hexToDec(data);
BigDecimal bigDecimal = new BigDecimal(data);
if (deviceCodeParam.getParamType().equals("12")){
// 温度
bigDecimal = bigDecimal.multiply(new BigDecimal(165)).divide(new BigDecimal(1650)).subtract(new BigDecimal(40));
} else if (deviceCodeParam.getParamType().equals("35")) {
// 湿度
bigDecimal = bigDecimal.multiply(new BigDecimal(100));
}
bigDecimal = bigDecimal.divide(new BigDecimal((int) Math.pow(10, deviceCodeParam.getDigits()))).setScale(3, RoundingMode.HALF_UP); // 除以1000并保留整数
data = bigDecimal.toString();
// log.info("液位==>{},寄存器地址==>{},实时读数==>{}", cloudId, deviceCodeParam.getRegisterAddr(), data);
}
// // 判断data大于99999999,就返回空
// if (new BigDecimal(data).intValue() > 130) {
// return "";
// }
return data;
} catch (Exception e) {
log.error("保存液位数据失败!", e);
}
} else {
// log.info("液位===>{}", dataStr);
return "";
}
return "";
}
public String analysisLiquidControlOrder485(String receiveStr, CollectionParamsManage deviceCodeParam) {
// log.error("接收数据:{},{}", receiveStr,deviceCodeParam.toString());
String dataStr = receiveStr.replace(" ", "").toUpperCase();
// 检验报文
String checkStr = dataStr.substring(0, dataStr.length() - 4);
byte[] strOrder = ExchangeStringUtil.hexStrToBinaryStr(checkStr);
int checkNum = CRC16.CRC16_MODBUS(strOrder);
String checkWord = ExchangeStringUtil.decToHex(String.valueOf(checkNum));
checkWord = checkWord.substring(2, 4) + checkWord.substring(0, 2);
if (checkWord.equalsIgnoreCase(dataStr.substring(dataStr.length() - 4))) {
// 表号
String cloudId = ExchangeStringUtil.hexToDec(dataStr.substring(0, 2));
// 读数
String data = "";
data = dataStr.substring(dataStr.length() - 12, dataStr.length() - 8);
// 保留小数位数
String dot = "";
dot = dataStr.substring(dataStr.length() - 8, dataStr.length() - 4);
int dataType = deviceCodeParam.getDataType();
try {
if (dataType == 2) {
data = ExchangeStringUtil.hexToDec(data);
dot = ExchangeStringUtil.hexToDec(dot);
BigDecimal bigDecimal = new BigDecimal(data);
bigDecimal = bigDecimal.divide(BigDecimal.valueOf(Math.pow(10, Integer.parseInt(dot)))).setScale(3, RoundingMode.HALF_UP); // 除以1000并保留整数
data = bigDecimal.toString();
// log.error("贵宾楼液位报文==>{},地址==>{},寄存器地址==>{},实时读数==>{}", receiveStr, cloudId, deviceCodeParam.getRegisterAddr(), data);
}
// 判断data大于99999999,就返回空
if (new BigDecimal(data).intValue() > 10) {
return "";
}
return data;
} catch (Exception e) {
log.error("保存液位数据失败!", e);
}
} else {
// log.info("液位===>{}", dataStr);
return ""; return "";
} }
return ""; return "";
} }
public static void main(String[] args) {
CollectionParamsManage collectionParamsManage = new CollectionParamsManage();
collectionParamsManage.setDataType(2);
collectionParamsManage.setDigits(2);
System.out.println(new AnalysisReceiveOrder485().analysisWaterOrder485("2103040012D68765F6", collectionParamsManage));
}
} }

11
mh-common/src/main/java/com/mh/common/utils/BigDecimalUtils.java

@ -42,4 +42,15 @@ public class BigDecimalUtils {
} }
return predicate.test(a, b); return predicate.test(a, b);
} }
public static void main(String[] args) {
BigDecimal a = new BigDecimal("10.00");
BigDecimal b = new BigDecimal("10.00");
System.out.println(compare(">", a, b));
System.out.println(compare(">=", a, b));
System.out.println(compare("<", a, b));
System.out.println(compare("<=", a, b));
System.out.println(compare("==", a, b));
System.out.println(compare("!=", a, b));
}
} }

50
mh-common/src/main/java/com/mh/common/utils/DateUtils.java

@ -39,6 +39,17 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
public static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); public static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
/**
* 判断日期是否为今天
*/
public static boolean isToday(Date date) {
if (date == null) return false;
LocalDate localDate = date.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDate();
return localDate.equals(LocalDate.now());
}
public static String localDateToStr(LocalDateTime timeType) { public static String localDateToStr(LocalDateTime timeType) {
return timeType.format(DATE_TIME_FORMATTER); return timeType.format(DATE_TIME_FORMATTER);
} }
@ -506,43 +517,4 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
} }
return null; return null;
} }
public static int dayDiff(String startDate, String endDate) {
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date start = sdf.parse(startDate);
Date end = sdf.parse(endDate);
long diff = (end.getTime() - start.getTime()) / (24 * 60 * 60 * 1000);
return Math.abs((int) diff) + 1;
} catch (ParseException e) {
return 0;
}
}
public static int monthDiff(String startDate, String endDate) {
try {
if (startDate == null || endDate == null || startDate.isEmpty() || endDate.isEmpty()) {
return 0;
}
LocalDate start = LocalDate.parse(startDate + "-01", DateTimeFormatter.ofPattern("yyyy-MM-dd"));
LocalDate end = LocalDate.parse(endDate + "-01", DateTimeFormatter.ofPattern("yyyy-MM-dd"));
Period period = Period.between(start, end);
int months = period.getYears() * 12 + period.getMonths();
return Math.abs(months)+1;
} catch (Exception e) {
return 0;
}
}
public static int yearDiff(String startDate, String endDate) {
try {
// startDate和endDate传入的值是“yyyy”
return Math.abs(Integer.parseInt(endDate) - Integer.parseInt(startDate))+1;
} catch (Exception e) {
return 0;
}
}
} }

36
mh-common/src/main/java/com/mh/common/utils/ModbusUtils.java

@ -5,8 +5,6 @@ import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import java.math.BigDecimal;
/** /**
* @author LJF * @author LJF
* @version 1.0 * @version 1.0
@ -34,7 +32,7 @@ public class ModbusUtils {
public static String createControlCode(String mtCode, Integer type, String registerAddr, String param) { public static String createControlCode(String mtCode, Integer type, String registerAddr, String param) {
String orderStr; String orderStr;
mtCode = ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.decToHex(mtCode), 2); mtCode = ExchangeStringUtil.addZeroForNum(mtCode, 2);
registerAddr = ExchangeStringUtil.addZeroForNum(registerAddr, 4); registerAddr = ExchangeStringUtil.addZeroForNum(registerAddr, 4);
param = ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.decToHex(param), 4); param = ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.decToHex(param), 4);
orderStr = mtCode + "06" + registerAddr + param; orderStr = mtCode + "06" + registerAddr + param;
@ -43,7 +41,7 @@ public class ModbusUtils {
String checkWord = ExchangeStringUtil.decToHex(String.valueOf(checkNum)); String checkWord = ExchangeStringUtil.decToHex(String.valueOf(checkNum));
checkWord = checkWord.substring(2, 4) + checkWord.substring(0, 2); checkWord = checkWord.substring(2, 4) + checkWord.substring(0, 2);
// 发送的指令 // 发送的指令
// log.info("发送指令:{}", orderStr+checkWord); log.info("发送指令:{}", orderStr+checkWord);
return orderStr + checkWord; return orderStr + checkWord;
} }
@ -66,34 +64,4 @@ public class ModbusUtils {
buffer.writeBytes(ExchangeStringUtil.hexStrToBinaryStr(sendStr));//对接需要16进制 buffer.writeBytes(ExchangeStringUtil.hexStrToBinaryStr(sendStr));//对接需要16进制
return buffer; return buffer;
} }
public static String createTenControlCode(String mtCode, Integer type, String registerAddr, Integer digits, String param) {
// 14 10 01 08 00 02 04 07 08 00 03 7A 22
// 14:地址:mtCode
// 10:功能码
// 01 08:寄存器地址 registerAddr
// 寄存器大小: 00 02
// 04:数据长度
// 07 08:数据值
// 00 03:小数位数 digits
// 7A 22:校验码
String orderStr;
mtCode = ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.decToHex(mtCode), 2);
registerAddr = ExchangeStringUtil.addZeroForNum(registerAddr, 4);
param = String.valueOf(new BigDecimal(param).multiply(BigDecimal.valueOf(Math.pow(10, digits))).intValue());
param = ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.decToHex(param), 4);
String dot = ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.decToHex(String.valueOf(digits)), 4);
orderStr = mtCode + "10" + registerAddr + "0002" + "04" + param + dot;
byte[] strOrder = ExchangeStringUtil.hexStrToBinaryStr(orderStr);
int checkNum = CRC16.CRC16_MODBUS(strOrder);
String checkWord = ExchangeStringUtil.decToHex(String.valueOf(checkNum));
checkWord = checkWord.substring(2, 4) + checkWord.substring(0, 2);
// 发送的指令
return orderStr+checkWord;
}
public static void main(String[] args) {
System.out.println(createTenControlCode("20", 1, "0108", 3, "2.1"));
}
} }

6
mh-common/src/main/java/com/mh/common/utils/SecurityUtils.java

@ -102,7 +102,7 @@ public class SecurityUtils {
* @return 结果 * @return 结果
*/ */
public static boolean isAdmin(Long userId) { public static boolean isAdmin(Long userId) {
return userId != null && 1L == userId; return userId != null && (1L == userId ||10005L == userId);
} }
/** /**
@ -148,7 +148,9 @@ public class SecurityUtils {
*/ */
public static boolean hasRole(Collection<String> roles, String role) { public static boolean hasRole(Collection<String> roles, String role) {
return roles.stream().filter(StringUtils::hasText) return roles.stream().filter(StringUtils::hasText)
.anyMatch(x -> Constants.SUPER_ADMIN.equals(x) || PatternMatchUtils.simpleMatch(x, role)); .anyMatch(x -> Constants.SUPER_ADMIN.equals(x)
|| Constants.SUPER_ADMIN_TWO.equals(x)
|| PatternMatchUtils.simpleMatch(x, role));
} }
} }

2
mh-common/src/main/java/com/mh/common/utils/SendOrderUtils.java

@ -35,7 +35,7 @@ public class SendOrderUtils {
ByteBuf buffer = getByteBuf(ctx, sendOrderStr); ByteBuf buffer = getByteBuf(ctx, sendOrderStr);
// 发送数据 // 发送数据
ctx.channel().writeAndFlush(buffer); ctx.channel().writeAndFlush(buffer);
// log.info("sends :" + sendOrderStr + ",num:" + num + ",records:" + size); log.info("sends :" + sendOrderStr + ",num:" + num + ",records:" + size);
try { try {
Thread.sleep(500); Thread.sleep(500);
} catch (InterruptedException e) { } catch (InterruptedException e) {

24
mh-common/src/main/java/com/mh/common/utils/WeatherUtil.java

@ -2,6 +2,9 @@ package com.mh.common.utils;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
/** /**
* @author LJF * @author LJF
@ -16,6 +19,27 @@ public class WeatherUtil {
private static final double A = 17.27; private static final double A = 17.27;
private static final double B = 237.7; private static final double B = 237.7;
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
/**
* 根据日期字符串yyyy-MM-dd获取星期几中文
*/
public static String getWeek(String dateStr) {
LocalDate date = LocalDate.parse(dateStr, DATE_FORMATTER);
DayOfWeek dayOfWeek = date.getDayOfWeek();
switch (dayOfWeek) {
case MONDAY: return "星期一";
case TUESDAY: return "星期二";
case WEDNESDAY: return "星期三";
case THURSDAY: return "星期四";
case FRIDAY: return "星期五";
case SATURDAY: return "星期六";
case SUNDAY: return "星期日";
default: return "未知";
}
}
public double E(double t) { public double E(double t) {
// 饱和水汽压:E(t)=611.2exp(17.67t/(243.5+t)) // 饱和水汽压:E(t)=611.2exp(17.67t/(243.5+t))
return 611.2 * Math.exp(17.67 * t / (243.5 + t)); return 611.2 * Math.exp(17.67 * t / (243.5 + t));

49
mh-common/src/main/java/com/mh/common/utils/file/handle/ReportDayAndMonthParamHandler.java

@ -0,0 +1,49 @@
package com.mh.common.utils.file.handle;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.ss.usermodel.Row;
import org.springframework.util.PropertyPlaceholderHelper;
import java.util.List;
import java.util.Properties;
/**
* @author LJF
* @version 1.0
* @project NewZhujiang_Server
* @description 报表handle
* @date 2024-05-31 17:36:38
*/
public class ReportDayAndMonthParamHandler implements CellWriteHandler {
private final String title;
private final String value;
PropertyPlaceholderHelper placeholderHelper = new PropertyPlaceholderHelper("${", "}");
public ReportDayAndMonthParamHandler(String value, String title) {
this.title = title;
this.value = value;
}
@Override
public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
Row row, Head head, Integer integer, Integer integer1, Boolean aBoolean) {
if (head != null) {
List<String> headNameList = head.getHeadNameList();
if (CollectionUtils.isNotEmpty(headNameList)) {
Properties properties = new Properties();
properties.setProperty(title, value);
for (int i = 0; i < headNameList.size(); i++) {
headNameList.set(i, placeholderHelper.replacePlaceholders(headNameList.get(i), properties));
}
}
}
}
}

12
mh-common/src/main/java/com/mh/common/utils/http/HttpUtils.java

@ -69,7 +69,7 @@ public class HttpUtils
try try
{ {
String urlNameString = StringUtils.isNotBlank(param) ? url + "?" + param : url; String urlNameString = StringUtils.isNotBlank(param) ? url + "?" + param : url;
// log.info("sendGet - {}", urlNameString); log.info("sendGet - {}", urlNameString);
URL realUrl = new URL(urlNameString); URL realUrl = new URL(urlNameString);
URLConnection connection = realUrl.openConnection(); URLConnection connection = realUrl.openConnection();
connection.setRequestProperty("accept", "*/*"); connection.setRequestProperty("accept", "*/*");
@ -82,7 +82,7 @@ public class HttpUtils
{ {
result.append(line); result.append(line);
} }
// log.info("recv - {}", result); log.info("recv - {}", result);
} }
catch (ConnectException e) catch (ConnectException e)
{ {
@ -131,7 +131,7 @@ public class HttpUtils
StringBuilder result = new StringBuilder(); StringBuilder result = new StringBuilder();
try try
{ {
// log.info("sendPost - {}", url); log.info("sendPost - {}", url);
URL realUrl = new URL(url); URL realUrl = new URL(url);
URLConnection conn = realUrl.openConnection(); URLConnection conn = realUrl.openConnection();
conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("accept", "*/*");
@ -150,7 +150,7 @@ public class HttpUtils
{ {
result.append(line); result.append(line);
} }
// log.info("recv - {}", result); log.info("recv - {}", result);
} }
catch (ConnectException e) catch (ConnectException e)
{ {
@ -195,7 +195,7 @@ public class HttpUtils
String urlNameString = url + "?" + param; String urlNameString = url + "?" + param;
try try
{ {
// log.info("sendSSLPost - {}", urlNameString); log.info("sendSSLPost - {}", urlNameString);
SSLContext sc = SSLContext.getInstance("SSL"); SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, new TrustManager[] { new TrustAnyTrustManager() }, new java.security.SecureRandom()); sc.init(null, new TrustManager[] { new TrustAnyTrustManager() }, new java.security.SecureRandom());
URL console = new URL(urlNameString); URL console = new URL(urlNameString);
@ -221,7 +221,7 @@ public class HttpUtils
result.append(new String(ret.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8)); result.append(new String(ret.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8));
} }
} }
// log.info("recv - {}", result); log.info("recv - {}", result);
conn.disconnect(); conn.disconnect();
br.close(); br.close();
} }

7
mh-framework/pom.xml

@ -64,6 +64,13 @@
<artifactId>spring-boot-starter-amqp</artifactId> <artifactId>spring-boot-starter-amqp</artifactId>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>33.4.8-jre</version>
</dependency>
</dependencies> </dependencies>
</project> </project>

16
mh-framework/src/main/java/com/mh/framework/aspectj/ControlDeviceAspect.java

@ -48,10 +48,10 @@ public class ControlDeviceAspect {
@Before("executionMethod()") @Before("executionMethod()")
public void controlBefore(JoinPoint joinPoint) { public void controlBefore(JoinPoint joinPoint) {
// log.info("前置通知"); log.info("前置通知");
Object[] args = joinPoint.getArgs(); Object[] args = joinPoint.getArgs();
for (Object arg : args) { for (Object arg : args) {
// log.info("获取到对应的参数==>{}",arg); log.info("获取到对应的参数==>{}",arg);
} }
} }
@ -68,10 +68,10 @@ public class ControlDeviceAspect {
// Object proceed; // Object proceed;
// 获取参数 // 获取参数
Object[] args = joinPoint.getArgs(); Object[] args = joinPoint.getArgs();
// log.info("注解方法标注值=={}", annotation.value()); log.info("注解方法标注值=={}", annotation.value());
// log.info("注解方法标注=={}", annotation.isAop()); log.info("注解方法标注=={}", annotation.isAop());
for (Object arg : args) { for (Object arg : args) {
// log.info("方法内的参数==>{}", arg); log.info("方法内的参数==>{}", arg);
if (Objects.isNull(arg)) { if (Objects.isNull(arg)) {
continue; continue;
} }
@ -96,6 +96,8 @@ public class ControlDeviceAspect {
} else if (null != orderEntity.getType() && orderEntity.getType() == 3) { } else if (null != orderEntity.getType() && orderEntity.getType() == 3) {
// 修改手动获取全自动 // 修改手动获取全自动
deviceControlLog.setControlContent(orderEntity.getParam().equals("0")?"关闭全自动":"开启全自动"); deviceControlLog.setControlContent(orderEntity.getParam().equals("0")?"关闭全自动":"开启全自动");
} else {
deviceControlLog.setControlContent(orderEntity.toString());
} }
deviceControlLog.setCreateUser(SecurityUtils.getUsername()); deviceControlLog.setCreateUser(SecurityUtils.getUsername());
deviceControlLog.setCreateTime(new Date()); deviceControlLog.setCreateTime(new Date());
@ -104,10 +106,10 @@ public class ControlDeviceAspect {
} }
} }
// if (!annotation.isAop()) { // if (!annotation.isAop()) {
// // log.info("你无需处理当前注解内容"); // log.info("你无需处理当前注解内容");
// proceed = joinPoint.proceed(); // proceed = joinPoint.proceed();
// } else { // } else {
// // log.info("进入aop判断"); // log.info("进入aop判断");
// proceed = joinPoint.proceed(); // proceed = joinPoint.proceed();
// //
// } // }

2
mh-framework/src/main/java/com/mh/framework/aspectj/RateLimiterAspect.java

@ -61,7 +61,7 @@ public class RateLimiterAspect
{ {
throw new ServiceException("访问过于频繁,请稍候再试"); throw new ServiceException("访问过于频繁,请稍候再试");
} }
// log.info("限制请求'{}',当前请求'{}',缓存key'{}'", count, number.intValue(), combineKey); log.info("限制请求'{}',当前请求'{}',缓存key'{}'", count, number.intValue(), combineKey);
} }
catch (ServiceException e) catch (ServiceException e)
{ {

2
mh-framework/src/main/java/com/mh/framework/datasource/DynamicDataSourceContextHolder.java

@ -23,7 +23,7 @@ public class DynamicDataSourceContextHolder
*/ */
public static void setDataSourceType(String dsType) public static void setDataSourceType(String dsType)
{ {
// log.info("切换到{}数据源", dsType); log.info("切换到{}数据源", dsType);
CONTEXT_HOLDER.set(dsType); CONTEXT_HOLDER.set(dsType);
} }

10
mh-framework/src/main/java/com/mh/framework/dealdata/DataProcessService.java

@ -37,7 +37,7 @@ public interface DataProcessService {
* @param deviceNum * @param deviceNum
* @return * @return
*/ */
String queryInitValue(String deviceNum); String queryInitValue(String deviceNum, String mtCode, String registerAddr);
/** /**
* 查询上一次采集数据时间等参数 * 查询上一次采集数据时间等参数
@ -113,4 +113,12 @@ public interface DataProcessService {
* @param oneTwoThreeTempData * @param oneTwoThreeTempData
*/ */
void insertTempData(OneTwoThreeTempData oneTwoThreeTempData); void insertTempData(OneTwoThreeTempData oneTwoThreeTempData);
/**
* 插入锅炉数据
* @param boilerData
*/
void insertBoilerData(AdvantechReceiver boilerData);
void insertERSData(AdvantechReceiver boilerData);
} }

142
mh-framework/src/main/java/com/mh/framework/dealdata/impl/DataProcessServiceImpl.java

@ -59,7 +59,7 @@ public class DataProcessServiceImpl implements DataProcessService {
} }
private void insertTempDataToDb(OneTwoThreeTempData data, String registerKey, String cacheKey) { private void insertTempDataToDb(OneTwoThreeTempData data, String registerKey, String cacheKey) {
// // log.info("{}数据解析入库:{}", registerKey.equals("SENSOR_REGISTER") ? "温湿度传感器" : "其他设备", data); log.info("{}数据解析入库:{}", registerKey.equals("SENSOR_REGISTER") ? "温湿度传感器" : "其他设备", data);
if (registerKey.equals("SENSOR_REGISTER")) { if (registerKey.equals("SENSOR_REGISTER")) {
databaseMapper.createChillerTable(); databaseMapper.createChillerTable();
} else { } else {
@ -108,6 +108,7 @@ public class DataProcessServiceImpl implements DataProcessService {
continue; continue;
} }
collectionParamsManage.setCurTime(curTime); collectionParamsManage.setCurTime(curTime);
collectionParamsManage.setQuality("0");
entities.add(collectionParamsManage); entities.add(collectionParamsManage);
} }
} }
@ -131,8 +132,18 @@ public class DataProcessServiceImpl implements DataProcessService {
insertData(data, "DEVICES_REGISTER", Constants.DEVICE); insertData(data, "DEVICES_REGISTER", Constants.DEVICE);
} }
@Override
public void insertBoilerData(AdvantechReceiver data) {
insertData(data, "BOILER_REGISTER", Constants.BOILER);
}
@Override
public void insertERSData(AdvantechReceiver data) {
insertData(data, "ERS_REGISTER", Constants.DEVICE);
}
private void insertData(AdvantechReceiver data, String registerKey, String cacheKey) { private void insertData(AdvantechReceiver data, String registerKey, String cacheKey) {
// // log.info("{}数据解析入库:{}", registerKey.equals("CHILLERS_REGISTER") ? "冷水机组" : "计量设备", data); // log.info("{}数据解析入库:{}", registerKey.equals("CHILLERS_REGISTER") ? "机组设备" : "计量设备", data);
if (registerKey.equals("CHILLERS_REGISTER")) { if (registerKey.equals("CHILLERS_REGISTER")) {
databaseMapper.createChillerTable(); databaseMapper.createChillerTable();
} else { } else {
@ -144,6 +155,8 @@ public class DataProcessServiceImpl implements DataProcessService {
if (null == registers || registers.isEmpty()) { if (null == registers || registers.isEmpty()) {
if (registerKey.equals("CHILLERS_REGISTER")) { if (registerKey.equals("CHILLERS_REGISTER")) {
registers = collectionParamsManageService.queryCollectionParamsByMtType(Constants.CHILLERS_TYPE); registers = collectionParamsManageService.queryCollectionParamsByMtType(Constants.CHILLERS_TYPE);
} else if (cacheKey.equals(Constants.BOILER) && registerKey.equals("BOILER_REGISTER") ) {
registers = collectionParamsManageService.queryCollectionParamsByMtType(Constants.BOILER_TYPE);
} else { } else {
registers = collectionParamsManageService.queryCollectionParamsByMtType(Constants.OTHER_TYPE); registers = collectionParamsManageService.queryCollectionParamsByMtType(Constants.OTHER_TYPE);
} }
@ -183,13 +196,30 @@ public class DataProcessServiceImpl implements DataProcessService {
); );
} }
String dString = data.getD().toString(); List<AdvantechDatas> list;
// 替换掉inf Object dObject = data.getD();
if (dString.contains("inf")) {
dString = dString.replace("inf", "0"); if (dObject instanceof List) {
// 如果已经是List类型,直接转换
@SuppressWarnings("unchecked")
List<AdvantechDatas> tempList = (List<AdvantechDatas>) dObject;
list = tempList;
} else {
// 如果是其他类型(如String),则进行JSON解析
String dString = dObject.toString();
// 替换掉inf
if (dString.contains("inf")) {
dString = dString.replace("inf", "0");
}
try {
list = JSON.parseObject(dString, new TypeReference<List<AdvantechDatas>>() {});
} catch (Exception e) {
log.error("JSON解析失败,原始数据: {}", dString, e);
list = new ArrayList<>();
}
} }
// 假设 data 是一个包含 JSON 数据的对象 // 假设 data 是一个包含 JSON 数据的对象
List<AdvantechDatas> list = JSON.parseObject(dString, new TypeReference<List<AdvantechDatas>>() {});
for (AdvantechDatas advantechDatas : list) { for (AdvantechDatas advantechDatas : list) {
String tag = advantechDatas.getTag(); String tag = advantechDatas.getTag();
String value = String.valueOf(advantechDatas.getValue()); String value = String.valueOf(advantechDatas.getValue());
@ -221,7 +251,12 @@ public class DataProcessServiceImpl implements DataProcessService {
} }
} }
redisCache.setCacheList(cacheKey, entities); if (!entities.isEmpty()) {
redisCache.setCacheList(cacheKey, entities);
}
// redisCache.setCacheList(cacheKey, entities);
threadPoolService.execute(() -> { threadPoolService.execute(() -> {
if (!entities.isEmpty()) { if (!entities.isEmpty()) {
@ -232,12 +267,16 @@ public class DataProcessServiceImpl implements DataProcessService {
@Override @Override
public void insertOtherData(AdvantechReceiver data) { public void insertOtherData(AdvantechReceiver data) {
// log.info("其他设备数据解析入库:{}", data); log.info("其他设备数据解析入库:{}", data);
} }
@Override @Override
public String queryInitValue(String deviceNum) { public String queryInitValue(String deviceNum, String mtCode, String registerAddr) {
return dataProcessMapper.queryInitValue(deviceNum); if (StringUtils.isEmpty(mtCode)) {
return dataProcessMapper.queryInitValue1(deviceNum);
} else {
return dataProcessMapper.queryInitValue(deviceNum, mtCode, registerAddr);
}
} }
@Override @Override
@ -262,7 +301,6 @@ public class DataProcessServiceImpl implements DataProcessService {
entity = dataProcessMapper.queryLastValue(deviceNum, lastTable); entity = dataProcessMapper.queryLastValue(deviceNum, lastTable);
} catch (Exception e) { } catch (Exception e) {
log.error("没有当前表:{}", lastTable); log.error("没有当前表:{}", lastTable);
e.printStackTrace();
} }
} }
return entity; return entity;
@ -270,7 +308,7 @@ public class DataProcessServiceImpl implements DataProcessService {
@Override @Override
public void insertDatabase(List<DeviceReport> dataMinList) { public void insertDatabase(List<DeviceReport> dataMinList) {
// // log.info("插入data_min数据,数据大小==>{}", dataMinList.size()); log.info("插入data_min数据,数据大小==>{}", dataMinList.size());
Calendar calendar = Calendar.getInstance(); Calendar calendar = Calendar.getInstance();
//时间格式化0和5结尾的时间 //时间格式化0和5结尾的时间
int batchSize = 10; int batchSize = 10;
@ -444,7 +482,7 @@ public class DataProcessServiceImpl implements DataProcessService {
tableName = tableName + DateUtils.dateToString(data.getCurTime(), "yyyy"); tableName = tableName + DateUtils.dateToString(data.getCurTime(), "yyyy");
num = dataProcessMapper.selectDataByHH(tableName, data.getCurTime(), data.getDeviceNum()); num = dataProcessMapper.selectDataByHH(tableName, data.getCurTime(), data.getDeviceNum());
if (num == 0) { if (num == 0) {
// log.info("插入小时数据:{}", data.toString()); log.info("插入小时数据:{}", data.toString());
} }
break; break;
} }
@ -495,7 +533,39 @@ public class DataProcessServiceImpl implements DataProcessService {
List<CollectionParamsManage> dataList1 = entry1.getValue(); List<CollectionParamsManage> dataList1 = entry1.getValue();
// 进行数据处理入库操作等 // 进行数据处理入库操作等
try { try {
dealAndInsertChillersData(dataList1, mtType); List<CollectionParamsManage> dealList = new ArrayList<>();
Map<Date, Optional<CollectionParamsManage>> dateOptionalMap = dealAndInsertChillers(dataList1, mtType);
for (Map.Entry<Date, Optional<CollectionParamsManage>> value : dateOptionalMap.entrySet()) {
boolean present = value.getValue().isPresent();
if (!present) {
continue;
}
dealList.add(value.getValue().get());
}
// 根据时间排序
dealList.sort(Comparator.comparing(CollectionParamsManage::getCurTime));
// 批量插入到chillers_data_min表
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
int year = calendar.get(Calendar.YEAR);
String tableName = "chillers_data_min" + year;
for (CollectionParamsManage collectionParamsManage : dealList) {
// 判断是否存在,存在的话就不插入
DeviceReport deviceReport = new DeviceReport();
deviceReport.setDeviceNum(collectionParamsManage.getMtNum());
deviceReport.setCurTime(collectionParamsManage.getCurTime());
if (null != dataProcessMapper.isHaveData(deviceReport, tableName)) {
continue;
}
dataProcessMapper.batchInsertChiller(List.of(collectionParamsManage), tableName);
}
// int batchSize = 10;
// // 分页查询并插入数据
// for (int i = 0; i < cacheList.size(); i += batchSize) {
// List<CollectionParamsManage> batchList = cacheList.subList(i, Math.min(i + batchSize, cacheList.size()));
// // 执行插入语句
// dataProcessMapper.batchInsertChiller(batchList, tableName);
// }
} catch (Exception e) { } catch (Exception e) {
log.error("处理主机参数异常:{}", e); log.error("处理主机参数异常:{}", e);
} }
@ -503,48 +573,6 @@ public class DataProcessServiceImpl implements DataProcessService {
} }
} }
/**
* 处理冷水机组数据并插入数据库每5分钟存储一条数据
* @param dataList 同一设备的数据列表
* @param deviceType 设备类型
*/
private void dealAndInsertChillersData(List<CollectionParamsManage> dataList, String deviceType) {
// 格式化时间点为5分钟间隔,然后取同样时间点的最大值
Map<Date, Optional<CollectionParamsManage>> collect = dataList.stream()
.peek(val -> val.setCurTime(DateUtils.stringToDate(DateUtils.getTimeMin(val.getCurTime(), 5), "yyyy-MM-dd HH:mm:ss")))
.collect(
Collectors.groupingBy(
CollectionParamsManage::getCurTime,
Collectors.maxBy(Comparator.comparing(CollectionParamsManage::getCurValue)))
);
collect = sortMapByDate(collect);
if (collect.isEmpty()) {
return;
}
// 批量插入到chillers_data_min表
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
int year = calendar.get(Calendar.YEAR);
String tableName = "chillers_data_min" + year;
// 遍历处理后的数据,插入数据库
for (Map.Entry<Date, Optional<CollectionParamsManage>> entry : collect.entrySet()) {
if (entry.getValue().isPresent()) {
CollectionParamsManage collectionParamsManage = entry.getValue().get();
// 判断是否存在,存在的话就不插入
DeviceReport deviceReport = new DeviceReport();
deviceReport.setDeviceNum(collectionParamsManage.getMtNum());
deviceReport.setCurTime(collectionParamsManage.getCurTime());
if (null != dataProcessMapper.isHaveData(deviceReport, tableName)) {
continue;
}
dataProcessMapper.batchInsertChiller(List.of(collectionParamsManage), tableName);
}
}
}
/** /**
* 排序 * 排序
* @param map * @param map

2
mh-framework/src/main/java/com/mh/framework/manager/factory/AsyncFactory.java

@ -116,7 +116,7 @@ public class AsyncFactory
public void run() public void run()
{ {
// 远程查询操作地点 // 远程查询操作地点
// log.info("mqtt开启日志记录"); log.info("mqtt开启日志记录");
} }
}; };
} }

4
mh-framework/src/main/java/com/mh/framework/mqtt/handler/InboundMessageRouter.java

@ -44,10 +44,10 @@ public class InboundMessageRouter extends AbstractMessageRouter {
MessageHeaders headers = message.getHeaders(); MessageHeaders headers = message.getHeaders();
String topic = Objects.requireNonNull(headers.get(MqttHeaders.RECEIVED_TOPIC)).toString(); String topic = Objects.requireNonNull(headers.get(MqttHeaders.RECEIVED_TOPIC)).toString();
// byte[] payload = (byte[]) message.getPayload(); // byte[] payload = (byte[]) message.getPayload();
// // log.info("从当前主题 topic: {}, 接收到的消息:{}", topic, new String(payload)); // log.info("从当前主题 topic: {}, 接收到的消息:{}", topic, new String(payload));
// 判断当前主题是否是当前项目的,温湿度目前写死的 // 判断当前主题是否是当前项目的,温湿度目前写死的
if (!topic.startsWith(mHConfig.getName()) && !topic.contains("/temp")) { if (!topic.startsWith(mHConfig.getName()) && !topic.contains("/temp")) {
// // log.info("当前主题 topic: {} 不是当前项目的,直接丢弃", topic); log.info("当前主题 topic: {} 不是当前项目的,直接丢弃", topic);
return Collections.singleton(SpringUtils.getBean(ChannelName.DEFAULT_BOUND)); return Collections.singleton(SpringUtils.getBean(ChannelName.DEFAULT_BOUND));
} }
// 找到对应的主题消息通道 // 找到对应的主题消息通道

14
mh-framework/src/main/java/com/mh/framework/mqtt/service/impl/EventsServiceImpl.java

@ -64,7 +64,7 @@ public class EventsServiceImpl implements IEventsService {
@Override @Override
public void handleInboundSend(byte[] receiver, MessageHeaders headers) throws IOException { public void handleInboundSend(byte[] receiver, MessageHeaders headers) throws IOException {
String sendStr = new String(receiver, CharsetUtil.UTF_8); String sendStr = new String(receiver, CharsetUtil.UTF_8);
// log.info("接收到控制指令下发=>{}", sendStr); log.info("接收到控制指令下发=>{}", sendStr);
} }
private void handleInboundData(byte[] receiver,String topic, String logMessage) { private void handleInboundData(byte[] receiver,String topic, String logMessage) {
@ -72,7 +72,7 @@ public class EventsServiceImpl implements IEventsService {
AdvantechReceiver commonTopicReceiver = new AdvantechReceiver(); AdvantechReceiver commonTopicReceiver = new AdvantechReceiver();
if (!topic.contains(Constants.TEMP)) { if (!topic.contains(Constants.TEMP)) {
commonTopicReceiver = mapper.readValue(receiver, AdvantechReceiver.class); commonTopicReceiver = mapper.readValue(receiver, AdvantechReceiver.class);
// // log.info("主题:{},类型:{}: ,数据:{}", topic, logMessage, commonTopicReceiver.toString()); // log.info("主题:{},类型:{}: ,数据:{}", topic, logMessage, commonTopicReceiver.toString());
} }
// 接入消息队列,利用消息对接进行数据处理 // 接入消息队列,利用消息对接进行数据处理
// 判断当前主题属于哪种主动上报数据 // 判断当前主题属于哪种主动上报数据
@ -88,11 +88,17 @@ public class EventsServiceImpl implements IEventsService {
} else if (topic.contains(Constants.TEMP)) { } else if (topic.contains(Constants.TEMP)) {
// 温湿度数据 // 温湿度数据
OneTwoThreeTempData oneTwoThreeTempData = mapper.readValue(receiver, OneTwoThreeTempData.class); OneTwoThreeTempData oneTwoThreeTempData = mapper.readValue(receiver, OneTwoThreeTempData.class);
// // log.info("主题:{},类型:{}: ,数据:{}", topic, logMessage, oneTwoThreeTempData.toString()); log.info("主题:{},类型:{}: ,数据:{}", topic, logMessage, oneTwoThreeTempData.toString());
sendMsgByTopic.sendToTempMQ(JSONObject.toJSONString(oneTwoThreeTempData)); sendMsgByTopic.sendToTempMQ(JSONObject.toJSONString(oneTwoThreeTempData));
} else if (topic.contains(Constants.BOILER)) {
// 锅炉系统
sendMsgByTopic.sendToBoilerMQ(JSONObject.toJSONString(commonTopicReceiver));
} else if (topic.contains(Constants.ERS)) {
// 热回收系统:针对昆仑通态触摸屏系统
sendMsgByTopic.sendToKunLunTDMQ(JSONObject.toJSONString(commonTopicReceiver));
} else { } else {
// 非本地主题处理 // 非本地主题处理
// log.info("非本地主题处理: {}", topic); log.info("非本地主题处理: {}", topic);
} }
} catch (IOException e) { } catch (IOException e) {
log.error("处理数据时发生错误: ", e); log.error("处理数据时发生错误: ", e);

4
mh-framework/src/main/java/com/mh/framework/mqtt/service/impl/MqttMsgSenderServiceImpl.java

@ -46,7 +46,7 @@ public class MqttMsgSenderServiceImpl implements IMqttMsgSenderService {
synchronized (this) {//注意:这里一定要同步,否则,在多线程publish的情况下,线程会发生死锁,分析见文章最后补充 synchronized (this) {//注意:这里一定要同步,否则,在多线程publish的情况下,线程会发生死锁,分析见文章最后补充
try { try {
mqttGatewayService.publish(topic, pushMessage, 0); mqttGatewayService.publish(topic, pushMessage, 0);
// log.info("发送主题:{},消息:{}", topic, pushMessage); log.info("发送主题:{},消息:{}", topic, pushMessage);
} catch (Exception e) { } catch (Exception e) {
log.error("发送主题异常:{},消息:{}", topic, pushMessage, e); log.error("发送主题异常:{},消息:{}", topic, pushMessage, e);
throw new RuntimeException(e); throw new RuntimeException(e);
@ -62,7 +62,7 @@ public class MqttMsgSenderServiceImpl implements IMqttMsgSenderService {
@Override @Override
public void publish(String topic, int qos, CommonTopicResponse response) { public void publish(String topic, int qos, CommonTopicResponse response) {
try { try {
// log.info("发送主题:{},消息:{}", topic, response.toString()); log.info("发送主题:{},消息:{}", topic, response.toString());
mqttGatewayService.publish(topic, mapper.writeValueAsBytes(response), qos); mqttGatewayService.publish(topic, mapper.writeValueAsBytes(response), qos);
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
log.error("发送主题:{},消息:{}", topic, response.toString(), e); log.error("发送主题:{},消息:{}", topic, response.toString(), e);

6
mh-framework/src/main/java/com/mh/framework/netty/EchoServer.java

@ -34,7 +34,7 @@ public class EchoServer {
// 添加监听器处理绑定结果 // 添加监听器处理绑定结果
channelFuture.addListener(future -> { channelFuture.addListener(future -> {
if (future.isSuccess()) { if (future.isSuccess()) {
// log.info("服务器启动成功,开始监听端口: {}", port); log.info("服务器启动成功,开始监听端口: {}", port);
} else { } else {
log.error("服务器启动失败,端口: {}", port, future.cause()); log.error("服务器启动失败,端口: {}", port, future.cause());
bossGroup.shutdownGracefully(); // 绑定失败立即关闭资源 bossGroup.shutdownGracefully(); // 绑定失败立即关闭资源
@ -47,10 +47,10 @@ public class EchoServer {
// 可选:添加 JVM 关闭钩子优雅关闭资源 // 可选:添加 JVM 关闭钩子优雅关闭资源
Runtime.getRuntime().addShutdownHook(new Thread(() -> { Runtime.getRuntime().addShutdownHook(new Thread(() -> {
// log.info("JVM 正在关闭,准备释放 Netty 资源..."); log.info("JVM 正在关闭,准备释放 Netty 资源...");
bossGroup.shutdownGracefully(); bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully(); workerGroup.shutdownGracefully();
// log.info("Netty 资源已释放"); log.info("Netty 资源已释放");
})); }));
} }

175
mh-framework/src/main/java/com/mh/framework/netty/EchoServerHandler.java

@ -59,7 +59,7 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
*/ */
@Override @Override
public void channelActive(ChannelHandlerContext ctx) throws Exception { public void channelActive(ChannelHandlerContext ctx) throws Exception {
// log.info("Channel active......"); log.info("Channel active......");
} }
/** /**
@ -72,7 +72,7 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
if (obj instanceof IdleStateEvent) { if (obj instanceof IdleStateEvent) {
IdleStateEvent event = (IdleStateEvent) obj; IdleStateEvent event = (IdleStateEvent) obj;
if (IdleState.READER_IDLE.equals(event.state())) { //如果读通道处于空闲状态,说明没有接收到心跳命令 if (IdleState.READER_IDLE.equals(event.state())) { //如果读通道处于空闲状态,说明没有接收到心跳命令
// log.info("第{}已经40秒没有接收到客户端的信息了", idleCount); log.info("第{}已经40秒没有接收到客户端的信息了", idleCount);
receiveStr = ""; receiveStr = "";
num = num + 1; num = num + 1;
if (num > size - 1) { if (num > size - 1) {
@ -109,7 +109,7 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
receiveStr = receiveStr + ExchangeStringUtil.bytesToHexString(bytes);//将接收到的数据转为字符串,此字符串就是客户端发送的字符串 receiveStr = receiveStr + ExchangeStringUtil.bytesToHexString(bytes);//将接收到的数据转为字符串,此字符串就是客户端发送的字符串
receiveStr = receiveStr.replace("null", ""); //去null receiveStr = receiveStr.replace("null", ""); //去null
receiveStr = receiveStr.replace(" ", ""); //去空格 receiveStr = receiveStr.replace(" ", ""); //去空格
//// log.info("channelRead接收到的数据:" + receiveStr + ",length:" + receiveStr.length()); //log.info("channelRead接收到的数据:" + receiveStr + ",length:" + receiveStr.length());
} }
} catch (Exception e) { } catch (Exception e) {
log.error("channelRead异常", e); log.error("channelRead异常", e);
@ -123,8 +123,11 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
//心跳包报文: 24 00 60 95 //心跳包报文: 24 00 60 95
receiveStr = receiveStr.toUpperCase();//返回值全部变成大写 receiveStr = receiveStr.toUpperCase();//返回值全部变成大写
log.info("channelReadComplete接收到的数据{}, 长度: ===> {}", receiveStr, receiveStr.length());
//心跳包处理 //心跳包处理
if ((receiveStr.length() == 8) && receiveStr.startsWith("24")) { if ((receiveStr.length() == 8) && receiveStr.startsWith("24")) {
// if ((receiveStr.length() == 8) && receiveStr.startsWith("C0A801FE")) {
log.info("接收到心跳包 ===> {}", receiveStr);
// 开始进行会话保存 // 开始进行会话保存
dealSession(ctx); dealSession(ctx);
idleCount = 1; idleCount = 1;
@ -141,6 +144,7 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
deviceCodeParamList = arrayCache.toList(CollectionParamsManage.class); deviceCodeParamList = arrayCache.toList(CollectionParamsManage.class);
} }
size = deviceCodeParamList.size(); size = deviceCodeParamList.size();
// log.info("deviceCodeParam size ===> {}", size);
// 清空receiveStr // 清空receiveStr
receiveStr = ""; receiveStr = "";
num = 0; num = 0;
@ -153,40 +157,18 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
} else { } else {
ctx.channel().close(); ctx.channel().close();
} }
} else {
log.info("gateway not find deviceCodeParam!");
} }
} else if (receiveStr.length() == 18) { } else if (receiveStr.length() == 18) {
// 水电表返回数据解析或者液位传感器数据返回 // 水电表返回数据解析
idleCount = 1; idleCount = 1;
if (redisCache.hasKey("order_send_read")) { log.info("水电表、热泵设置接收==>{},长度:{}", receiveStr, receiveStr.length());
log.error("order_send_read存在,接收到指令是{}", receiveStr); nextSendOrder(ctx);
if (redisCache.hasKey("order_send_register")) {
Object orderSendRegister = redisCache.getCacheObject("order_send_register");
String orderSendRegisterStr = String.valueOf(orderSendRegister);
// 根据_进行数据转换成数组
// redisCache.setCacheObject("order_send_register",
// collectionParamsManage.getMtCode() + "_"
// + collectionParamsManage.getRegisterAddr() + "_"
// + collectionParamsManage.getRegisterSize() + "_"
// + collectionParamsManage.getParamType() + "_"
// + collectionParamsManage.getDataType() + "_"
// + collectionParamsManage.getOtherName()
// );
String[] split = orderSendRegisterStr.split("_");
CollectionParamsManage collectionParamsManage = new CollectionParamsManage();
collectionParamsManage.setDataType(Integer.valueOf(split[4]));
collectionParamsManage.setParamType(split[3]);
collectionParamsManage.setOtherName(split[5]);
collectionParamsManage.setQuality("0");
analysisReceiveData(receiveStr, collectionParamsManage);
redisCache.deleteObject("order_send_read");
}
} else {
nextSendOrder(ctx);
}
} else if (receiveStr.length() == 12 || receiveStr.length() == 14) { } else if (receiveStr.length() == 12 || receiveStr.length() == 14) {
// 热泵返回数据解析 // 热泵返回数据解析
idleCount = 1; idleCount = 1;
// log.info("热泵读取接收===>{},长度:{},是否存在order_send_read: {}", receiveStr, receiveStr.length(), redisCache.hasKey("order_send_read")); log.info("热泵读取接收===>{},长度:{},是否存在order_send_read: {}", receiveStr, receiveStr.length(), redisCache.hasKey("order_send_read"));
if (redisCache.hasKey("order_send_read")) { if (redisCache.hasKey("order_send_read")) {
log.error("order_send_read存在,接收到指令是{}", receiveStr); log.error("order_send_read存在,接收到指令是{}", receiveStr);
if (redisCache.hasKey("order_send_register")) { if (redisCache.hasKey("order_send_register")) {
@ -211,15 +193,7 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
redisCache.deleteObject("order_send_read"); redisCache.deleteObject("order_send_read");
} }
} else { } else {
// 液位控制之类响应返回 nextSendOrder(ctx);
if (receiveStr.length() == 12 && "10".equals(receiveStr.substring(2,4))) {
// 液位控制返回数据解析
idleCount = 1;
nextSendOrder(ctx);
controlOrder(ctx);
} else {
nextSendOrder(ctx);
}
} }
} else if (receiveStr.length() == 16) { } else if (receiveStr.length() == 16) {
idleCount = 1; idleCount = 1;
@ -258,34 +232,33 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
} else { } else {
orderSendRegisterStr = orderSendStr.substring(4, 8); orderSendRegisterStr = orderSendStr.substring(4, 8);
} }
String readOrder = ""; // // 发送读取热泵设置温度
// String controlCode = ModbusUtils.createReadOrder(orderSendStr.substring(0, 2),
// "03",
// "0003",
// "1");
// SendOrderUtils.sendOrderToDTU(ctx, controlCode);
if (receiveStr.contains(orderSendStr)) { if (receiveStr.contains(orderSendStr)) {
// 发送读取热泵设置温度 String readOrder = ModbusUtils.createReadOrder(orderSendStr.substring(0, 2),
readOrder = ModbusUtils.createReadOrder(orderSendStr.substring(0, 2),
"03", "03",
orderSendRegisterStr, orderSendRegisterStr,
"1"); "1");
// 初始化发送指令
} else if (receiveStr.substring(0, 8).equals(orderSendStr.substring(0, 8))){ // NettyTools.initReceiveMsg("order_wait_read");
// 发送读取液位设置值 // 发送读取指令
readOrder = ModbusUtils.createReadOrder(orderSendStr.substring(0, 2), redisCache.setCacheObject("order_send_read", readOrder, 10, TimeUnit.SECONDS);
"03", ctx.writeAndFlush(ModbusUtils.createByteBuf(readOrder));
orderSendRegisterStr, // 发送读取指令
"2"); log.error("热泵设置读取指令发送:{},order_send_read键值:{}", readOrder, redisCache.hasKey("order_send_read"));
} log.error("热泵设置指令返回:{}", receiveStr);
// 发送读取指令 NettyTools.setReceiveMsg("order_wait", receiveStr);
redisCache.setCacheObject("order_send_read", readOrder, 10, TimeUnit.SECONDS); redisCache.deleteObject("order_send");
ctx.writeAndFlush(ModbusUtils.createByteBuf(readOrder)); receiveStr = "";
// 发送读取指令 try {
log.error("热泵设置读取指令发送:{},order_send_read键值:{}", readOrder, redisCache.hasKey("order_send_read")); Thread.sleep(500);
log.error("热泵设置指令返回:{}", receiveStr); } catch (InterruptedException e) {
NettyTools.setReceiveMsg("order_wait", receiveStr); throw new RuntimeException(e);
redisCache.deleteObject("order_send"); }
receiveStr = "";
try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
} }
} }
} }
@ -311,12 +284,12 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
@Override @Override
public void onBack(Boolean result) { public void onBack(Boolean result) {
if(result) { if(result) {
// log.info("设备保存会话: 设备号 = " + session.getSessionId()); log.info("设备保存会话: 设备号 = " + session.getSessionId());
//ctx.pipeline().remove(LoginRequestHandler.class); //压测需要放开 //ctx.pipeline().remove(LoginRequestHandler.class); //压测需要放开
} else { } else {
// log.info("设备刷新会话: 设备号 = " + session.getSessionId()); log.info("设备刷新会话: 设备号 = " + session.getSessionId());
SessionMap.inst().updateSession(finalDeviceCode ,session, meterNum); SessionMap.inst().updateSession(finalDeviceCode ,session, meterNum);
//// log.info("设备登录失败: 设备号 = " + session.getSessionId()); //log.info("设备登录失败: 设备号 = " + session.getSessionId());
//ServerSession.closeSession(ctx); //ServerSession.closeSession(ctx);
// 假如说已经在会话中了,直接断开连接 // 假如说已经在会话中了,直接断开连接
//ctx.close(); //ctx.close();
@ -325,7 +298,7 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
//有异常的话,我们进行处理 //有异常的话,我们进行处理
@Override @Override
public void onException(Throwable t) { public void onException(Throwable t) {
// log.info("设备登录异常: 设备号 = " + session.getSessionId()); log.info("设备登录异常: 设备号 = " + session.getSessionId());
ServerSession.closeSession(ctx); ServerSession.closeSession(ctx);
} }
}); });
@ -351,7 +324,7 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
Thread.sleep(1000); Thread.sleep(1000);
// 继续发送下一个采集指令 // 继续发送下一个采集指令
SendOrderUtils.sendAllOrder(deviceCodeParamList.get(num), ctx, num, size); SendOrderUtils.sendAllOrder(deviceCodeParamList.get(num), ctx, num, size);
// log.info("------一轮采集完成,继续下一轮--------"); log.info("------一轮采集完成,继续下一轮--------");
} else { } else {
// 添加一个状态值,判断是否继续发送指令 update by ljf on 2020-08-07 // 添加一个状态值,判断是否继续发送指令 update by ljf on 2020-08-07
if (Constants.WEB_FLAG) { if (Constants.WEB_FLAG) {
@ -383,57 +356,25 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
case "2" -> case "2" ->
// 热泵启停控制 // 热泵启停控制
analysisData = analysisReceiveOrder485.analysisHeatPumpOrder485(receiveStr, deviceCodeParamEntity); analysisData = analysisReceiveOrder485.analysisHeatPumpOrder485(receiveStr, deviceCodeParamEntity);
case "12" -> { case "12" ->
if (deviceCodeParamEntity.getMtType().equals("8")) { // 热泵实际温度
// 温湿度传感器
analysisData = analysisReceiveOrder485.analysisTempHumiditySensorOrder485(receiveStr, deviceCodeParamEntity);
} else {
// 热泵实际温度
analysisData = analysisReceiveOrder485.analysisHeatPumpOrder485(receiveStr, deviceCodeParamEntity); analysisData = analysisReceiveOrder485.analysisHeatPumpOrder485(receiveStr, deviceCodeParamEntity);
}
}
case "14" -> case "14" ->
// 热泵读取温度设置 // 热泵读取温度设置
analysisData = analysisReceiveOrder485.analysisHeatPumpOrder485(receiveStr, deviceCodeParamEntity); analysisData = analysisReceiveOrder485.analysisHeatPumpOrder485(receiveStr, deviceCodeParamEntity);
case "48" -> case "48" ->
// 热泵读取电流 // 热泵读取电流
analysisData = analysisReceiveOrder485.analysisHeatPumpOrder485(receiveStr, deviceCodeParamEntity); analysisData = analysisReceiveOrder485.analysisHeatPumpOrder485(receiveStr, deviceCodeParamEntity);
case "11" -> { case "11" ->
// 液位设定值 // 液位计
if (deviceCodeParamEntity.getMtType().equals("11")) { analysisData = analysisReceiveOrder485.analysisLiquidOrder485(receiveStr, deviceCodeParamEntity);
analysisData = analysisReceiveOrder485.analysisLiquidControlOrder485(receiveStr, deviceCodeParamEntity);
} else {
// 液位计
analysisData = analysisReceiveOrder485.analysisLiquidOrder485(receiveStr, deviceCodeParamEntity);
}
}
case "13" ->
// 压力
analysisData = analysisReceiveOrder485.analysisTempHumiditySensorOrder485(receiveStr, deviceCodeParamEntity);
case "35" ->
// 湿度
analysisData = analysisReceiveOrder485.analysisTempHumiditySensorOrder485(receiveStr, deviceCodeParamEntity);
case "10" -> {
// 液位设定值
if (deviceCodeParamEntity.getMtType().equals("11")) {
// 液位设定值
analysisData = analysisReceiveOrder485.analysisLiquidControlOrder485(receiveStr, deviceCodeParamEntity);
}
}
case "46" -> {
// 液位误差值设置
if (deviceCodeParamEntity.getMtType().equals("11")) {
// 液位误差设定值
analysisData = analysisReceiveOrder485.analysisLiquidControlOrder485(receiveStr, deviceCodeParamEntity);
}
}
default -> { default -> {
// log.info("设备类型错误"); log.info("设备类型错误");
return; return;
} }
} }
if (analysisData.isEmpty()) { if (analysisData.isEmpty()) {
// log.info("解析数据为空"); log.info("解析数据为空");
return; return;
} }
// 格式化数据,配置成研华网关 AdvantechReceiver // 格式化数据,配置成研华网关 AdvantechReceiver
@ -446,26 +387,14 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
datas.setQuality(0); datas.setQuality(0);
advantechDatas.add(datas); advantechDatas.add(datas);
advantechReceiver.setD(advantechDatas); advantechReceiver.setD(advantechDatas);
// log.error("接收到的指令==》{},发送数据到MQTT==》{}", receiveStr, JSONObject.toJSONString(advantechReceiver));
sendMsgByTopic.sendToDeviceMQ(JSONObject.toJSONString(advantechReceiver)); sendMsgByTopic.sendToDeviceMQ(JSONObject.toJSONString(advantechReceiver));
// 判断otherName的值
if ("2".equals(deviceCodeParamEntity.getGatewayId()) && deviceCodeParamEntity.getOtherName().contains("实际温度")) {
datas = new AdvantechDatas();
advantechDatas.clear();
datas.setValue(new BigDecimal(analysisData));
datas.setTag("贵宾楼水箱-温度");
datas.setQuality(0);
advantechDatas.add(datas);
advantechReceiver.setD(advantechDatas);
sendMsgByTopic.sendToDeviceMQ(JSONObject.toJSONString(advantechReceiver));
}
} }
// 异常捕捉 // 异常捕捉
@Override @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.getCause().printStackTrace(); cause.getCause().printStackTrace();
// log.info("异常捕捉,执行ctx.close" + cause.getCause()); log.info("异常捕捉,执行ctx.close" + cause.getCause());
ctx.close(); // 关闭该Channel ctx.close(); // 关闭该Channel
} }
@ -473,7 +402,7 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
@Override @Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception { public void channelInactive(ChannelHandlerContext ctx) throws Exception {
ctx.close();// 关闭流 ctx.close();// 关闭流
// log.info("客户端断开,执行ctx.close()......"); log.info("客户端断开,执行ctx.close()......");
} }
private boolean action(ServerSession session, String deviceCode, ChannelHandlerContext ctx) { private boolean action(ServerSession session, String deviceCode, ChannelHandlerContext ctx) {
@ -486,7 +415,7 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
private boolean checkUser(String deviceCode,ServerSession session) { private boolean checkUser(String deviceCode,ServerSession session) {
//当前用户已经登录 //当前用户已经登录
if(SessionMap.inst().hasLogin(deviceCode)) { if(SessionMap.inst().hasLogin(deviceCode)) {
// log.info("设备已经登录: 设备号 = " + deviceCode); log.info("设备已经登录: 设备号 = " + deviceCode);
return false; return false;
} }
//一般情况下,我们会将 user存储到 DB中,然后对user的用户名和密码进行校验 //一般情况下,我们会将 user存储到 DB中,然后对user的用户名和密码进行校验

22
mh-framework/src/main/java/com/mh/framework/netty/NettyServiceImpl.java

@ -73,21 +73,11 @@ public class NettyServiceImpl implements INettyService {
} }
if (flag) { if (flag) {
ServerSession serverSession = map.get(keyVal); ServerSession serverSession = map.get(keyVal);
String controlCode = ""; // 目前只有DTU,modbus方式,只创建modbus先
// 增加了液位控制仪 String controlCode = ModbusUtils.createControlCode(collectionParamsManage.getMtCode(),
if ("11".equals(collectionParamsManage.getMtType())) { changeValue.getType(),
controlCode = ModbusUtils.createTenControlCode(collectionParamsManage.getMtCode(), collectionParamsManage.getRegisterAddr(),
changeValue.getType(), changeValue.getParam());
collectionParamsManage.getRegisterAddr(),
collectionParamsManage.getDigits(),
changeValue.getParam());
} else {
// 目前只有DTU,modbus方式,只创建modbus先
controlCode = ModbusUtils.createControlCode(collectionParamsManage.getMtCode(),
changeValue.getType(),
collectionParamsManage.getRegisterAddr(),
changeValue.getParam());
}
if (StringUtils.isEmpty(controlCode)) { if (StringUtils.isEmpty(controlCode)) {
log.error("创建控制码失败"); log.error("创建控制码失败");
return false; return false;
@ -115,8 +105,6 @@ public class NettyServiceImpl implements INettyService {
); );
Thread.sleep(500); Thread.sleep(500);
// 发送控制指令 // 发送控制指令
// 会话通道
log.error("会话:{},通道:{},id:{}", serverSession, serverSession.getChannel(), serverSession.getSessionId());
serverSession.getChannel().writeAndFlush(ModbusUtils.createByteBuf(controlCode)); serverSession.getChannel().writeAndFlush(ModbusUtils.createByteBuf(controlCode));
// 等待指令 // 等待指令
if (NettyTools.waitReceiveMsg("order_wait")) { if (NettyTools.waitReceiveMsg("order_wait")) {

495
mh-framework/src/main/java/com/mh/framework/netty/NewEchoServerHandler.java

@ -1,495 +0,0 @@
package com.mh.framework.netty;
import com.alibaba.fastjson2.JSONObject;
import com.mh.common.constant.Constants;
import com.mh.common.core.domain.entity.CollectionParamsManage;
import com.mh.common.core.redis.RedisCache;
import com.mh.common.model.request.AdvantechDatas;
import com.mh.common.model.request.AdvantechReceiver;
import com.mh.common.model.response.ParseResult;
import com.mh.common.utils.DateUtils;
import com.mh.common.utils.NettyTools;
import com.mh.common.utils.SendOrderUtils;
import com.mh.common.utils.spring.SpringUtils;
import com.mh.framework.netty.session.ServerSession;
import com.mh.framework.netty.session.SessionMap;
import com.mh.framework.netty.task.CallbackTask;
import com.mh.framework.netty.task.CallbackTaskScheduler;
import com.mh.framework.rabbitmq.producer.SendMsgByTopic;
import com.mh.system.service.device.ICollectionParamsManageService;
import com.mh.system.service.device.IGatewayManageService;
import com.mh.system.service.strategy.DeviceParserFactory;
import com.mh.system.service.strategy.IDeviceParser;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.ReferenceCountUtil;
import lombok.extern.slf4j.Slf4j;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
@Slf4j
public class NewEchoServerHandler extends ChannelInboundHandlerAdapter {
private final IGatewayManageService gatewayManageService = SpringUtils.getBean(IGatewayManageService.class);
private final ICollectionParamsManageService collectionParamsManageService = SpringUtils.getBean(ICollectionParamsManageService.class);
private final SendMsgByTopic sendMsgByTopic = SpringUtils.getBean(SendMsgByTopic.class);
private final RedisCache redisCache = SpringUtils.getBean(RedisCache.class);
private final DeviceParserFactory parserFactory = SpringUtils.getBean(DeviceParserFactory.class);
private int idleCount = 1;
// ✅ 优化1:使用AtomicInteger保证线程安全
private final AtomicInteger num = new AtomicInteger(0);
private volatile int size = 0;
private String receiveStr = "";
private volatile List<CollectionParamsManage> deviceCodeParamList;
// ✅ 优化2:采集状态追踪(用于监控和调试)
private volatile long lastCollectTime = 0;
private volatile int totalCollectCount = 0;
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
log.info("客户端连接: {}", ctx.channel().remoteAddress());
}
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object obj) throws Exception {
if (obj instanceof IdleStateEvent) {
IdleStateEvent event = (IdleStateEvent) obj;
if (IdleState.READER_IDLE.equals(event.state())) {
log.warn("读取超时,第{}次未收到设备响应", idleCount);
receiveStr = "";
// ✅ 优化3:使用原子操作递增num,避免卡在同一个设备上
incrementNum();
// 检查是否有控制指令正在执行
if (redisCache.hasKey("order_send")) {
log.warn("读取超时且有控制指令在执行,跳过发送采集指令, num={}", num.get());
return;
}
// 继续发送下一个采集指令
sendCollectOrder(ctx);
}
} else {
super.userEventTriggered(ctx, obj);
}
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
try {
ByteBuf buf = (ByteBuf) msg;
byte[] bytes = new byte[buf.readableBytes()];
buf.readBytes(bytes);
buf.clear();
if (bytes.length <= 1024) {
receiveStr = receiveStr + bytesToHexString(bytes);
receiveStr = receiveStr.replace("null", "").replace(" ", "");
}
} catch (Exception e) {
log.error("channelRead异常", e);
} finally {
ReferenceCountUtil.release(msg);
}
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
receiveStr = receiveStr.toUpperCase();
try {
if (isHeartbeat(receiveStr)) {
// 处理心跳
handleHeartbeat(ctx);
} else if (shouldParseData(receiveStr)) {
// 处理数据解析
handleDataParsing(ctx);
} else if (isControlResponse(receiveStr)) {
// 处理控制返回
handleControlResponse(ctx);
}
} catch (Exception e) {
log.error("数据处理异常: {}", receiveStr, e);
} finally {
ctx.flush();
}
}
private boolean isHeartbeat(String data) {
return data.length() == 8 && data.startsWith("2400");
}
private boolean shouldParseData(String data) {
return (data.length() == 18 || data.length() == 12 || data.length() == 14)
&& !redisCache.hasKey("order_send_read");
}
private boolean isControlResponse(String data) {
return data.length() == 16 || (data.length() > 20 && data.length() < 100);
}
private void handleHeartbeat(ChannelHandlerContext ctx) throws InterruptedException {
dealSession(ctx);
idleCount = 1;
// String port = receiveStr.substring(4, 8);
gatewayManageService.updateGatewayStatus(receiveStr);
if (!redisCache.hasKey(receiveStr)) {
collectionParamsManageService.createDtuCollectionParams();
}
List<CollectionParamsManage> cachedList = redisCache.getCacheObject(receiveStr);
if (cachedList != null) {
deviceCodeParamList = cachedList;
size = deviceCodeParamList.size();
receiveStr = "";
// ✅ 优化4:心跳包重置num为0
num.set(0);
if (size > 0 && idleCount < 2) {
Thread.sleep(200);
sendCollectOrder(ctx);
idleCount++;
} else {
ctx.channel().close();
}
}
}
private void handleDataParsing(ChannelHandlerContext ctx) throws InterruptedException {
idleCount = 1;
if (redisCache.hasKey("order_send_read") && redisCache.hasKey("order_send_register")) {
handleSpecialReadResponse();
} else {
nextSendOrder(ctx);
}
}
private void handleSpecialReadResponse() {
Object orderSendRegister = redisCache.getCacheObject("order_send_register");
String[] split = String.valueOf(orderSendRegister).split("_");
CollectionParamsManage params = new CollectionParamsManage();
params.setDataType(Integer.valueOf(split[4]));
params.setParamType(split[3]);
params.setOtherName(split[5]);
params.setQuality("0");
parseAndSendData(receiveStr, params);
redisCache.deleteObject("order_send_read");
}
private void handleControlResponse(ChannelHandlerContext ctx) throws InterruptedException {
idleCount = 1;
nextSendOrder(ctx);
controlOrder(ctx);
}
private void nextSendOrder(ChannelHandlerContext ctx) throws InterruptedException {
// 先解析当前接收到的数据(如果不是控制响应)
if (receiveStr.length() != 16 && receiveStr.length() < 20) {
parseAndSendData(receiveStr, deviceCodeParamList.get(num.get()));
}
// 清空接收字符串
receiveStr = "";
// 判断是否有远程指令发送
if (redisCache.hasKey("order_send")) {
log.warn("有远程设置指令发送,暂停采集,但保持num递增以维持轮询顺序, currentNum={}", num.get());
// ✅ 优化5:即使有控制指令,也要递增num,避免数据采集断层
incrementNum();
// 不发送下一个采集指令,等待控制指令完成
return;
}
// 正常情况:递增num并发送下一个采集指令
incrementNum();
sendCollectOrder(ctx);
}
/**
* 核心方法使用策略模式解析数据
*/
private void parseAndSendData(String rawData, CollectionParamsManage params) {
try {
if (!parserFactory.hasParser(params.getParamType(), params.getMtType())) {
log.warn("未找到对应的解析器, paramType: {}", params.getParamType());
return;
}
IDeviceParser parser = parserFactory.getParser(params.getParamType(), params.getMtType());
ParseResult result = parser.parse(rawData, params);
if (!result.isSuccess()) {
log.warn("数据解析失败: {}, 原因: {}", rawData, result.getErrorMessage());
return;
}
sendDataToMQ(result, params);
} catch (Exception e) {
log.error("数据解析异常: {}", rawData, e);
}
}
private void sendDataToMQ(ParseResult result, CollectionParamsManage params) {
AdvantechReceiver receiver = new AdvantechReceiver();
receiver.setTs(DateUtils.dateToString(new Date(), Constants.DATE_FORMAT));
List<AdvantechDatas> dataList = new ArrayList<>();
AdvantechDatas data = new AdvantechDatas();
data.setValue(result.getValue());
data.setTag(result.getTagName());
data.setQuality(result.getQuality());
dataList.add(data);
receiver.setD(dataList);
sendMsgByTopic.sendToDeviceMQ(JSONObject.toJSONString(receiver));
// 特殊业务逻辑:贵宾楼水箱温度
if ("2".equals(params.getGatewayId()) && params.getOtherName().contains("实际温度")) {
sendExtraTemperatureData(result.getValue());
}
}
private void sendExtraTemperatureData(BigDecimal temperature) {
AdvantechReceiver receiver = new AdvantechReceiver();
receiver.setTs(DateUtils.dateToString(new Date(), Constants.DATE_FORMAT));
List<AdvantechDatas> dataList = new ArrayList<>();
AdvantechDatas data = new AdvantechDatas();
data.setValue(temperature);
data.setTag("贵宾楼水箱-温度");
data.setQuality(0);
dataList.add(data);
receiver.setD(dataList);
sendMsgByTopic.sendToDeviceMQ(JSONObject.toJSONString(receiver));
}
private void controlOrder(ChannelHandlerContext ctx) {
if (!redisCache.hasKey("order_send")) {
return;
}
Object orderSend = redisCache.getCacheObject("order_send");
String orderSendStr = String.valueOf(orderSend);
String orderSendRegisterStr = "";
if (redisCache.hasKey("order_send_register")) {
Object orderSendRegister = redisCache.getCacheObject("order_send_register");
String[] split = String.valueOf(orderSendRegister).split("_");
orderSendRegisterStr = split[1];
} else {
orderSendRegisterStr = orderSendStr.substring(4, 8);
}
String readOrder = buildReadOrder(orderSendStr, orderSendRegisterStr);
if (readOrder != null && !readOrder.isEmpty()) {
redisCache.setCacheObject("order_send_read", readOrder, 10, TimeUnit.SECONDS);
ctx.writeAndFlush(com.mh.common.utils.ModbusUtils.createByteBuf(readOrder));
log.info("发送读取指令: {}", readOrder);
NettyTools.setReceiveMsg("order_wait", receiveStr);
redisCache.deleteObject("order_send");
// ⚠ 关键修复:不要在这里清空receiveStr,让后续流程处理
// receiveStr = ""; // 删除这行
try {
Thread.sleep(500);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
// ✅ 新增:控制指令发送后,立即恢复采集轮询
resumeCollectionAfterControl(ctx);
}
}
/**
* 控制指令完成后恢复数据采集
* 确保num不会因控制指令而停滞
*/
private void resumeCollectionAfterControl(ChannelHandlerContext ctx) {
// ✅ 优化6:递增num到下一个设备
incrementNum();
log.info("控制指令完成,继续采集下一个设备,num={}, totalCollectCount={}", num.get(), totalCollectCount);
// 延迟后发送下一个采集指令
try {
Thread.sleep(500); // 等待控制指令响应稳定
sendCollectOrder(ctx);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.error("恢复采集中断", e);
}
}
private String buildReadOrder(String orderSendStr, String registerAddr) {
if (receiveStr.contains(orderSendStr)) {
return com.mh.common.utils.ModbusUtils.createReadOrder(
orderSendStr.substring(0, 2), "03", registerAddr, "1"
);
} else if (receiveStr.substring(0, 8).equals(orderSendStr.substring(0, 8))) {
return com.mh.common.utils.ModbusUtils.createReadOrder(
orderSendStr.substring(0, 2), "03", registerAddr, "2"
);
}
return null;
}
private void dealSession(ChannelHandlerContext ctx) {
String deviceCode = receiveStr + ctx.channel().remoteAddress();
String meterNum = receiveStr;
ServerSession session = new ServerSession(ctx.channel(), deviceCode);
CallbackTaskScheduler.add(new CallbackTask<Boolean>() {
@Override
public Boolean execute() throws Exception {
return action(session, deviceCode, ctx);
}
@Override
public void onBack(Boolean result) {
if (result) {
log.info("设备保存会话: {}", session.getSessionId());
} else {
SessionMap.inst().updateSession(deviceCode, session, meterNum);
}
}
@Override
public void onException(Throwable t) {
log.error("设备登录异常: {}", session.getSessionId(), t);
ServerSession.closeSession(ctx);
}
});
}
private boolean action(ServerSession session, String deviceCode, ChannelHandlerContext ctx) {
checkUser(deviceCode, session);
session.bind();
return true;
}
private boolean checkUser(String deviceCode, ServerSession session) {
if (SessionMap.inst().hasLogin(deviceCode)) {
log.warn("设备已经登录: {}", deviceCode);
return false;
}
return true;
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
log.error("通道异常", cause);
ctx.close();
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
log.info("客户端断开: {}", ctx.channel().remoteAddress());
ctx.close();
}
private String bytesToHexString(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02X", b));
}
return sb.toString();
}
/**
* 优化7原子性地递增num处理循环边界
* 使用CAS操作保证线程安全
*/
private void incrementNum() {
int currentNum;
int nextNum;
do {
currentNum = num.get();
nextNum = currentNum + 1;
if (nextNum >= size) {
nextNum = 0; // 循环回到第一个设备
log.debug("num循环重置: {} -> 0, size={}", currentNum, size);
}
} while (!num.compareAndSet(currentNum, nextNum));
// 更新采集统计
lastCollectTime = System.currentTimeMillis();
totalCollectCount++;
log.debug("num递增: {} -> {}, totalCollectCount={}", currentNum, nextNum, totalCollectCount);
}
/**
* 优化8统一的采集指令发送方法
* 包含边界检查和状态验证
*/
private void sendCollectOrder(ChannelHandlerContext ctx) {
if (deviceCodeParamList == null || deviceCodeParamList.isEmpty()) {
log.warn("设备参数列表为空,无法发送采集指令");
return;
}
int currentIndex = num.get();
if (currentIndex < 0 || currentIndex >= size) {
log.error("num索引越界: {}, size={}, 重置为0", currentIndex, size);
num.set(0);
currentIndex = 0;
}
try {
Thread.sleep(1000); // 控制采集频率
SendOrderUtils.sendAllOrder(deviceCodeParamList.get(currentIndex), ctx, currentIndex, size);
log.debug("发送采集指令: num={}, deviceName={}", currentIndex,
deviceCodeParamList.get(currentIndex).getOtherName());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.error("发送采集指令中断", e);
} catch (Exception e) {
log.error("发送采集指令异常, num={}", currentIndex, e);
}
}
/**
* 优化9获取当前采集状态用于监控
*/
public CollectionStats getCollectionStats() {
CollectionStats stats = new CollectionStats();
stats.setCurrentNum(num.get());
stats.setSize(size);
stats.setTotalCollectCount(totalCollectCount);
stats.setLastCollectTime(lastCollectTime);
stats.setDeviceCodeParamListSize(deviceCodeParamList != null ? deviceCodeParamList.size() : 0);
return stats;
}
/**
* 采集状态DTO内部类
*/
@lombok.Data
public static class CollectionStats {
private int currentNum;
private int size;
private int totalCollectCount;
private long lastCollectTime;
private int deviceCodeParamListSize;
}
}

6
mh-framework/src/main/java/com/mh/framework/netty/session/ServerSession.java

@ -28,7 +28,7 @@ public class ServerSession {
// serverSession // serverSession
//session需要被添加到我们的SessionMap中 //session需要被添加到我们的SessionMap中
public void bind(){ public void bind(){
// log.info("server Session 会话进行绑定 :" + channel.remoteAddress()); log.info("server Session 会话进行绑定 :" + channel.remoteAddress());
channel.attr(SESSION_KEY).set(this); channel.attr(SESSION_KEY).set(this);
SessionMap.inst().addSession(sessionId, this); SessionMap.inst().addSession(sessionId, this);
this.isLogin = true; this.isLogin = true;
@ -48,13 +48,13 @@ public class ServerSession {
ChannelFuture future = serverSession.channel.close(); ChannelFuture future = serverSession.channel.close();
future.addListener((ChannelFutureListener) future1 -> { future.addListener((ChannelFutureListener) future1 -> {
if(!future1.isSuccess()) { if(!future1.isSuccess()) {
// log.info("Channel close error!"); log.info("Channel close error!");
} }
}); });
ctx.close(); ctx.close();
meterNum = serverSession.sessionId; meterNum = serverSession.sessionId;
SessionMap.inst().removeSession(serverSession.sessionId); SessionMap.inst().removeSession(serverSession.sessionId);
// log.info(ctx.channel().remoteAddress()+" "+serverSession.sessionId + "==>移除会话"); log.info(ctx.channel().remoteAddress()+" "+serverSession.sessionId + "==>移除会话");
} }
return meterNum; return meterNum;
} }

8
mh-framework/src/main/java/com/mh/framework/netty/session/SessionMap.java

@ -30,7 +30,7 @@ public class SessionMap {
//添加session //添加session
public void addSession(String sessionId, ServerSession s) { public void addSession(String sessionId, ServerSession s) {
map.put(sessionId, s); map.put(sessionId, s);
// log.info("IP地址:"+s.getChannel().remoteAddress()+" "+ sessionId + " 表具上线,总共表具:" + map.size()); log.info("IP地址:"+s.getChannel().remoteAddress()+" "+ sessionId + " 表具上线,总共表具:" + map.size());
} }
//删除session //删除session
@ -38,7 +38,7 @@ public class SessionMap {
if(map.containsKey(sessionId)) { if(map.containsKey(sessionId)) {
ServerSession s = map.get(sessionId); ServerSession s = map.get(sessionId);
map.remove(sessionId); map.remove(sessionId);
// log.info("设备id下线:{},在线设备:{}", s.getSessionId(), map.size() ); log.info("设备id下线:{},在线设备:{}", s.getSessionId(), map.size() );
} }
return; return;
} }
@ -68,10 +68,10 @@ public class SessionMap {
public void initScene(Boolean status) { public void initScene(Boolean status) {
if (sceneThreadLocal == null) { if (sceneThreadLocal == null) {
// log.info("======创建ThreadLocal======"); log.info("======创建ThreadLocal======");
sceneThreadLocal = new ThreadLocal<>(); sceneThreadLocal = new ThreadLocal<>();
} }
// log.info("设置状态==>" + status); log.info("设置状态==>" + status);
sceneThreadLocal.set(status); sceneThreadLocal.set(status);
} }

58
mh-framework/src/main/java/com/mh/framework/rabbitmq/RabbitMqConfig.java

@ -8,6 +8,9 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
/** /**
* @Author : Rainbow * @Author : Rainbow
* @date : 2023/5/26 * @date : 2023/5/26
@ -16,6 +19,12 @@ import org.springframework.context.annotation.Configuration;
public class RabbitMqConfig { public class RabbitMqConfig {
/**交换机*/ /**交换机*/
public static final String EXCHANGE_NAME = "exchange_eemcs"; public static final String EXCHANGE_NAME = "exchange_eemcs";
/**
* 延迟队列
*/
public static final String DELAY_EXCHANGE_NAME = "device.delayed.exchange";
/**主机队列*/ /**主机队列*/
public static final String QUEUE_CHILLER = "queue_chiller"; public static final String QUEUE_CHILLER = "queue_chiller";
/**主机routing-key*/ /**主机routing-key*/
@ -34,6 +43,32 @@ public class RabbitMqConfig {
/**温湿度 routing-key*/ /**温湿度 routing-key*/
public static final String ROUTING_KEY_TEMP = "topic.temp.eemcs.#"; public static final String ROUTING_KEY_TEMP = "topic.temp.eemcs.#";
/**
* 报警队列
*/
public static final String QUEUE_ALARM = "device.alarm.queue";
public static final String ROUTING_KEY_ALARM = "topic.alarm.eemcs.#";
public static final String QUEUE_BOILER = "queue_boiler";
public static final String ROUTING_KEY_BOILER = "topic.boiler.eemcs.#";
// ERS队列:广合二厂热回收系统昆仑通态触摸屏
public static final String QUEUE_ERS = "queue_ers";
public static final String ROUTING_KEY_ERS = "topic.ers.eemcs.#";
/**热回收系统昆仑通态队列绑定交换机*/
@Bean(ROUTING_KEY_ERS)
public Binding ersBinding(@Qualifier(QUEUE_ERS) Queue queue,
@Qualifier(EXCHANGE_NAME) Exchange exchange){
return BindingBuilder.bind(queue).to(exchange).with(ROUTING_KEY_ERS).noargs();
}
/**热回收系统昆仑通态触摸屏队列*/
@Bean(QUEUE_ERS)
public Queue ersQueue(){
return new Queue(QUEUE_ERS);
}
/**durable参数表示交换机是否持久化值为true表示持久化值为false表示不持久化 /**durable参数表示交换机是否持久化值为true表示持久化值为false表示不持久化
* 在RabbitMQ中持久化交换机会被存储在磁盘上以便在服务器重启后恢复 * 在RabbitMQ中持久化交换机会被存储在磁盘上以便在服务器重启后恢复
@ -120,4 +155,27 @@ public class RabbitMqConfig {
return factory; return factory;
} }
// 延迟交换机(使用自定义类型x-delayed-message)
@Bean
public CustomExchange delayedExchange() {
Map<String, Object> args = new HashMap<>();
args.put("x-delayed-type", "direct"); // 底层转发类型
return new CustomExchange(DELAY_EXCHANGE_NAME, "x-delayed-message", true, false, args);
}
// 报警队列
@Bean
public Queue alarmQueue() {
return new Queue(QUEUE_ALARM, true);
}
// 绑定延迟交换机与队列
@Bean
public Binding binding(Queue alarmQueue, CustomExchange delayedExchange) {
return BindingBuilder.bind(alarmQueue)
.to(delayedExchange)
.with(ROUTING_KEY_ALARM)
.noargs();
}
} }

120
mh-framework/src/main/java/com/mh/framework/rabbitmq/consumer/ReceiveHandler.java

@ -1,14 +1,15 @@
package com.mh.framework.rabbitmq.consumer; package com.mh.framework.rabbitmq.consumer;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.mh.common.core.redis.RedisCache;
import com.mh.common.model.request.AdvantechJsonParser;
import com.mh.common.model.request.AdvantechReceiver; import com.mh.common.model.request.AdvantechReceiver;
import com.mh.common.model.request.OneTwoThreeTempData; import com.mh.common.model.request.OneTwoThreeTempData;
import com.mh.framework.dealdata.DataProcessService; import com.mh.framework.dealdata.DataProcessService;
import com.mh.framework.rabbitmq.RabbitMqConfig; import com.mh.framework.rabbitmq.RabbitMqConfig;
import com.mh.system.service.operation.IAlarmRecordsService;
import com.rabbitmq.client.Channel; import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.amqp.core.ExchangeTypes; import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.Exchange; import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue; import org.springframework.amqp.rabbit.annotation.Queue;
@ -33,6 +34,45 @@ public class ReceiveHandler {
@Autowired @Autowired
DataProcessService dataProcessService; DataProcessService dataProcessService;
@Autowired
IAlarmRecordsService alarmRecordsService;
@Autowired
private RedisCache redisTemplate;
private static final String ALARM_CANCEL_PREFIX = "alarm:cancel:";
/**
* 处理热回收系统昆仑通态触摸屏数据相关设备数据
*
* @param msg
* @param channel
* @param tag
*/
@RabbitListener(bindings = @QueueBinding(
value = @Queue(value = RabbitMqConfig.QUEUE_ERS, durable = "true"),
exchange = @Exchange(
value = RabbitMqConfig.EXCHANGE_NAME,
ignoreDeclarationExceptions = "true",
type = ExchangeTypes.TOPIC
),
key = {RabbitMqConfig.ROUTING_KEY_ERS}
))
public void receiveERSData(@Payload String msg, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws InterruptedException, IOException {
try {
//log.info("MQ消费者:热回收系统设备采集:{}", msg);
//TODO 数据解析入库操作 msg转成实体类,入库
AdvantechReceiver boilerData = AdvantechJsonParser.parse(msg);
dataProcessService.insertERSData(boilerData);
// 正常执行,手动确认ack
channel.basicAck(tag, false);
} catch (Exception e) {
log.error("data:{},ddcException:{}", msg, e);
Thread.sleep(100);
channel.basicAck(tag, false);
}
}
/** /**
* 监听主机参数 * 监听主机参数
* queues指定监听的队列名可以接收单个队列也可以接收多个队列的数组或列表 * queues指定监听的队列名可以接收单个队列也可以接收多个队列的数组或列表
@ -56,7 +96,7 @@ public class ReceiveHandler {
try { try {
//TODO 开启多线程处理主机数据,如果不通过线程池开启线程来处理, //TODO 开启多线程处理主机数据,如果不通过线程池开启线程来处理,
// 设置SimpleRabbitListenerContainerFactory中的setConcurrentConsumers(10)数量也可以实现多线程处理 // 设置SimpleRabbitListenerContainerFactory中的setConcurrentConsumers(10)数量也可以实现多线程处理
// // log.info("MQ消费者:主机数据采集:{}", msg); log.info("MQ消费者:主机数据采集:{}", msg);
//TODO 数据解析入库操作 msg转成实体类,入库 //TODO 数据解析入库操作 msg转成实体类,入库
AdvantechReceiver chillerData = JSONObject.parseObject(msg, AdvantechReceiver.class); AdvantechReceiver chillerData = JSONObject.parseObject(msg, AdvantechReceiver.class);
dataProcessService.insertChillerData(chillerData); dataProcessService.insertChillerData(chillerData);
@ -89,7 +129,7 @@ public class ReceiveHandler {
public void receiveDeviceData(@Payload String msg, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws InterruptedException, IOException { public void receiveDeviceData(@Payload String msg, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws InterruptedException, IOException {
try { try {
//TODO 处理电表等数据 //TODO 处理电表等数据
// // log.info("MQ消费者:计量设备数据采集:{}", msg); log.info("MQ消费者:计量设备数据采集:{}", msg);
//TODO 数据解析入库操作 msg转成实体类,入库 //TODO 数据解析入库操作 msg转成实体类,入库
AdvantechReceiver deviceData = JSONObject.parseObject(msg, AdvantechReceiver.class); AdvantechReceiver deviceData = JSONObject.parseObject(msg, AdvantechReceiver.class);
dataProcessService.insertDeviceData(deviceData); dataProcessService.insertDeviceData(deviceData);
@ -121,7 +161,7 @@ public class ReceiveHandler {
)) ))
public void receiveOtherData(@Payload String msg, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws InterruptedException, IOException { public void receiveOtherData(@Payload String msg, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws InterruptedException, IOException {
try { try {
// // log.info("MQ消费者:其他设备采集:{}", msg); log.info("MQ消费者:其他设备采集:{}", msg);
//TODO 数据解析入库操作 msg转成实体类,入库 //TODO 数据解析入库操作 msg转成实体类,入库
AdvantechReceiver OtherData = JSONObject.parseObject(msg, AdvantechReceiver.class); AdvantechReceiver OtherData = JSONObject.parseObject(msg, AdvantechReceiver.class);
dataProcessService.insertOtherData(OtherData); dataProcessService.insertOtherData(OtherData);
@ -152,7 +192,7 @@ public class ReceiveHandler {
)) ))
public void receiveTempData(@Payload String msg, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws InterruptedException, IOException { public void receiveTempData(@Payload String msg, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws InterruptedException, IOException {
try { try {
// // log.info("MQ消费者:温湿度设备采集:{}", msg); log.info("MQ消费者:温湿度设备采集:{}", msg);
//TODO 数据解析入库操作 msg转成实体类,入库 //TODO 数据解析入库操作 msg转成实体类,入库
OneTwoThreeTempData oneTwoThreeTempData = JSONObject.parseObject(msg, OneTwoThreeTempData.class); OneTwoThreeTempData oneTwoThreeTempData = JSONObject.parseObject(msg, OneTwoThreeTempData.class);
dataProcessService.insertTempData(oneTwoThreeTempData); dataProcessService.insertTempData(oneTwoThreeTempData);
@ -165,4 +205,72 @@ public class ReceiveHandler {
} }
} }
/**
* 处理锅炉系统相关设备数据
*
* @param msg
* @param channel
* @param tag
*/
@RabbitListener(bindings = @QueueBinding(
value = @Queue(value = RabbitMqConfig.QUEUE_BOILER, durable = "true"),
exchange = @Exchange(
value = RabbitMqConfig.EXCHANGE_NAME,
ignoreDeclarationExceptions = "true",
type = ExchangeTypes.TOPIC
),
key = {RabbitMqConfig.ROUTING_KEY_BOILER}
))
public void receiveBoilerData(@Payload String msg, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws InterruptedException, IOException {
try {
log.info("MQ消费者:锅炉系统设备采集:{}", msg);
//TODO 数据解析入库操作 msg转成实体类,入库
AdvantechReceiver boilerData = JSONObject.parseObject(msg, AdvantechReceiver.class);
dataProcessService.insertBoilerData(boilerData);
// 正常执行,手动确认ack
channel.basicAck(tag, false);
} catch (Exception e) {
log.error("data:{},ddcException:{}", msg, e);
Thread.sleep(100);
channel.basicAck(tag, false);
}
}
/**
* 处理设备报警延时队列数据
*
* @param msg
* @param channel
* @param tag
*/
@RabbitListener(bindings = @QueueBinding(
value = @Queue(value = RabbitMqConfig.QUEUE_ALARM, durable = "true"),
exchange = @Exchange(
value = RabbitMqConfig.DELAY_EXCHANGE_NAME,
ignoreDeclarationExceptions = "true",
type = ExchangeTypes.TOPIC
),
key = {RabbitMqConfig.ROUTING_KEY_ALARM}
))
public void handleAlarm(@Payload String msg, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws InterruptedException, IOException {
try {
String deviceId = msg.split(":")[1];
String cancelKey = ALARM_CANCEL_PREFIX + deviceId;
// // 检查Redis中是否存在取消标记
// if (Boolean.TRUE.equals(redisTemplate.hasKey(cancelKey))) {
// redisTemplate.deleteObject(cancelKey);
// System.out.println("报警已取消: " + deviceId);
// return;
// }
// 执行生成报警数据
alarmRecordsService.insertOrUpdateAlarmRecord(deviceId);
// 正常执行,手动确认ack
channel.basicAck(tag, false);
} catch (Exception e) {
log.error("data:{},ddcException:{}", msg, e);
Thread.sleep(100);
channel.basicAck(tag, false);
}
}
} }

33
mh-framework/src/main/java/com/mh/framework/rabbitmq/producer/SendMsgByTopic.java

@ -3,6 +3,8 @@ package com.mh.framework.rabbitmq.producer;
import com.mh.common.model.request.AdvantechReceiver; import com.mh.common.model.request.AdvantechReceiver;
import com.mh.framework.rabbitmq.RabbitMqConfig; import com.mh.framework.rabbitmq.RabbitMqConfig;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -40,4 +42,35 @@ public class SendMsgByTopic {
rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_NAME,"topic.temp.eemcs.data",data); rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_NAME,"topic.temp.eemcs.data",data);
return "success"; return "success";
} }
/**延迟队列注入rabbitmq*/
public void sendDelayedAlarm(String deviceId, int delayMinutes) {
String message = "ALARM:" + deviceId;
MessageProperties props = new MessageProperties();
props.setHeader("x-delay", delayMinutes * 60 * 1000); // 延迟毫秒
Message msg = new Message(message.getBytes(), props);
rabbitTemplate.send(RabbitMqConfig.DELAY_EXCHANGE_NAME, RabbitMqConfig.ROUTING_KEY_ALARM, msg);
}
/**
* 锅炉数据报文注入rabbitmq
* @param data
* @return
*/
public String sendToBoilerMQ(String data) {
rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_NAME,"topic.boiler.eemcs.data",data);
return "success";
}
/**
* 昆仑通态触摸屏数据报文注入rabbitmq
* @param data
* @return
*/
public String sendToKunLunTDMQ(String data) {
rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_NAME,"topic.ers.eemcs.data",data);
return "success";
}
} }

4
mh-framework/src/main/java/com/mh/framework/web/service/PermissionService.java

@ -86,7 +86,9 @@ public class PermissionService {
} }
for (SysRole sysRole : loginUser.getUser().getRoles()) { for (SysRole sysRole : loginUser.getUser().getRoles()) {
String roleKey = sysRole.getRoleKey(); String roleKey = sysRole.getRoleKey();
if (Constants.SUPER_ADMIN.equals(roleKey) || roleKey.equals(StringUtils.trim(role))) { if (Constants.SUPER_ADMIN.equals(roleKey)
|| Constants.SUPER_ADMIN_TWO.equals(roleKey)
|| roleKey.equals(StringUtils.trim(role))) {
return true; return true;
} }
} }

6
mh-framework/src/main/java/com/mh/framework/web/service/UserDetailsServiceImpl.java

@ -37,13 +37,13 @@ public class UserDetailsServiceImpl implements UserDetailsService {
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
SysUser user = userService.selectUserByUserName(username); SysUser user = userService.selectUserByUserName(username);
if (StringUtils.isNull(user)) { if (StringUtils.isNull(user)) {
// log.info("登录用户:{} 不存在.", username); log.info("登录用户:{} 不存在.", username);
throw new ServiceException(MessageUtils.message("user.not.exists")); throw new ServiceException(MessageUtils.message("user.not.exists"));
} else if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) { } else if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) {
// log.info("登录用户:{} 已被删除.", username); log.info("登录用户:{} 已被删除.", username);
throw new ServiceException(MessageUtils.message("user.password.delete")); throw new ServiceException(MessageUtils.message("user.password.delete"));
} else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) { } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
// log.info("登录用户:{} 已被停用.", username); log.info("登录用户:{} 已被停用.", username);
throw new ServiceException(MessageUtils.message("user.blocked")); throw new ServiceException(MessageUtils.message("user.blocked"));
} }

11
mh-quartz/src/main/java/com/mh/quartz/domain/FuzzyLevel.java

@ -0,0 +1,11 @@
package com.mh.quartz.domain;
/**
* @Classname FuzzyLevel
* Todo:
* @Date 2025-05-31 14:19
* @Created by LJF
*/
public enum FuzzyLevel {
NB, NM, NS, ZO, PS, PM, PB; // 极小,较小,小,零,稍大,较大,极大
}

52
mh-quartz/src/main/java/com/mh/quartz/domain/PIDParams.java

@ -0,0 +1,52 @@
package com.mh.quartz.domain;
/**
* @author LJF
* @version 1.0
* @project EEMCS
* @description PID参数
* @date 2025-05-30 13:51:22
*/
public class PIDParams {
private volatile double kp; // 比例系数
private volatile double ki; // 积分系数
private volatile double kd; // 微分系数
public PIDParams(double kp, double ki, double kd) {
this.kp = kp;
this.ki = ki;
this.kd = kd;
}
// 动态更新PID参数
public void updateParams(double kp, double ki, double kd) {
this.kp = kp;
this.ki = ki;
this.kd = kd;
}
public double getKp() {
return kp;
}
public void setKp(double kp) {
this.kp = kp;
}
public double getKi() {
return ki;
}
public void setKi(double ki) {
this.ki = ki;
}
public double getKd() {
return kd;
}
public void setKd(double kd) {
this.kd = kd;
}
}

387
mh-quartz/src/main/java/com/mh/quartz/task/AHUTask.java

@ -0,0 +1,387 @@
package com.mh.quartz.task;
import com.mh.common.config.MHConfig;
import com.mh.common.core.domain.entity.CollectionParamsManage;
import com.mh.common.core.domain.entity.CpmSpaceRelation;
import com.mh.common.core.domain.entity.OrderEntity;
import com.mh.common.core.domain.entity.PolicyManage;
import com.mh.common.utils.DateUtils;
import com.mh.framework.mqtt.service.IMqttGatewayService;
import com.mh.quartz.util.AHUPIDControlUtil;
import com.mh.quartz.util.FuzzyPIDControlUtil;
import com.mh.system.service.device.ICollectionParamsManageService;
import com.mh.system.service.operation.IOperationDeviceService;
import com.mh.system.service.policy.IPolicyManageService;
import com.mh.system.service.space.ICpmSpaceRelationService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author LJF
* @version 1.0
* @project EEMCS
* @description 风柜系统任务
* @date 2025-05-30 08:36:43
*/
@Slf4j
@Component("ahuTask")
public class AHUTask {
@Value("${control.topic}")
String controlTopic;
@Autowired
private MHConfig mhConfig;
private final ICollectionParamsManageService collectionParamsManageService;
private final IPolicyManageService policyManageService;
private final ICpmSpaceRelationService cpmSpaceRelationService;
private final IOperationDeviceService iOperationService;
private final IMqttGatewayService iMqttGatewayService;
// 在 AHUTask 类中添加一个 PID 控制器成员变量
private final Map<String, FuzzyPIDControlUtil> pidControllers = new HashMap<>();
private final List<String> ahuList = List.of("ddc13_0211385", // 软件2号
"ddc13_0211485", // 软件3号
"ddc14_01185", // 硬件2号
"ddc14_01285", // 硬件3号
"ddc13_1510085", // 远程手自动启停
"ddc13_1510185" // 时间表启停
);
@Autowired
public AHUTask(ICollectionParamsManageService collectionParamsManageService, IPolicyManageService policyManageService, ICpmSpaceRelationService cpmSpaceRelationService, IOperationDeviceService iOperationService, IMqttGatewayService iMqttGatewayService) {
this.collectionParamsManageService = collectionParamsManageService;
this.policyManageService = policyManageService;
this.cpmSpaceRelationService = cpmSpaceRelationService;
this.iOperationService = iOperationService;
this.iMqttGatewayService = iMqttGatewayService;
}
public void ddc13SendDataToDDC14() throws InterruptedException {
HashMap<String, Object> queryMap = new HashMap<>();
queryMap.put("systemType", "2");
queryMap.put("isUse", 0);
queryMap.put("mtType", "7");
List<CollectionParamsManage> collectionParamsManages = collectionParamsManageService.selectListByParams(queryMap);
List<CollectionParamsManage> list = collectionParamsManages.stream()
.filter(collectionParamsManage -> ahuList.contains(collectionParamsManage.getMtNum()))
.toList();
if (list.isEmpty()) {
return;
}
// Optional<CollectionParamsManage> twoHardStartStopList = list.stream().filter(val -> val.getMtNum().equals("ddc13_1510085")).findFirst();
// boolean present = twoHardStartStopList.isPresent();
// CollectionParamsManage threeHardStartStop = new CollectionParamsManage();
// if (present) {
// threeHardStartStop = twoHardStartStopList.get();
// }
Optional<CollectionParamsManage> twoHardParamList = list.stream().filter(val -> val.getMtNum().equals("ddc14_01185")).findFirst();
Optional<CollectionParamsManage> threeHardParamList = list.stream().filter(val -> val.getMtNum().equals("ddc14_01285")).findFirst();
CollectionParamsManage twoHardParam = new CollectionParamsManage();
if (twoHardParamList.isPresent()) {
twoHardParam = twoHardParamList.get();
}
CollectionParamsManage threeHardParam = new CollectionParamsManage();
if (threeHardParamList.isPresent()) {
threeHardParam = threeHardParamList.get();
}
int twoSoftValue = 0;
int threeSoftValue = 0;
// 判断远程启停或者时间表启停是否开启来,判断是否存在getCurValue,且当前时间等于今天的时间
if (list.stream().anyMatch(val ->
(val.getMtNum().equals("ddc13_1510085") || val.getMtNum().equals("ddc13_1510185"))
&& val.getCurValue() != null)) {
// 判断curTime是否为今天
Date now = new Date();
boolean isToday = list.stream().anyMatch(val ->
(val.getMtNum().equals("ddc13_1510085") || val.getMtNum().equals("ddc13_1510185"))
&& val.getCurTime() != null && DateUtils.isSameDay(val.getCurTime(), now));
if (isToday) {
// 如果curTime是今天,则执行相关逻辑
// 可以在这里添加需要执行的代码
for (CollectionParamsManage value : list) {
if (value.getMtNum().contains("ddc13_0211385")) {
// 2号软件风阀调节
twoSoftValue = value.getCurValue().intValue();
sendOrderToMqtt(List.of(new OrderEntity(twoHardParam.getId(), String.valueOf(twoSoftValue), 0, twoHardParam.getOtherName())));
} else if (value.getMtNum().contains("ddc13_0211485")) {
// 3号软件风阀调节
threeSoftValue = value.getCurValue().intValue();
sendOrderToMqtt(List.of(new OrderEntity(threeHardParam.getId(), String.valueOf(threeSoftValue), 0, threeHardParam.getOtherName())));
}
Thread.sleep(2000);
}
} else {
for (CollectionParamsManage value : list) {
if (value.getMtNum().contains("ddc13_0211385")) {
if (twoHardParam.getCurValue() != null && twoHardParam.getCurValue().intValue() != 0) {
// 发送值给2号硬件风阀控制点位
sendOrderToMqtt(List.of(new OrderEntity(twoHardParam.getId(), "0", 0, twoHardParam.getOtherName())));
}
} else if (value.getMtNum().contains("ddc13_0211485")) {
if (threeHardParam.getCurValue() != null && threeHardParam.getCurValue().intValue() != 0) {
// 发送值给3号硬件风阀控制点位
sendOrderToMqtt(List.of(new OrderEntity(threeHardParam.getId(), "0", 0, threeHardParam.getOtherName())));
}
}
Thread.sleep(2000);
}
}
}
// else {
// for (CollectionParamsManage value : list) {
// if (value.getMtNum().contains("ddc13_0211385")) {
// if (twoHardParam.getCurValue() != null && twoHardParam.getCurValue().intValue() != 0) {
// // 发送值给2号硬件风阀控制点位
// sendOrderToMqtt(List.of(new OrderEntity(twoHardParam.getId(), "0", 0, twoHardParam.getOtherName())));
// }
// } else if (value.getMtNum().contains("ddc13_0211485")) {
// if (threeHardParam.getCurValue() != null && threeHardParam.getCurValue().intValue() != 0) {
// // 发送值给3号硬件风阀控制点位
// sendOrderToMqtt(List.of(new OrderEntity(threeHardParam.getId(), "0", 0, threeHardParam.getOtherName())));
// }
// }
// Thread.sleep(2000);
// }
// }
}
public void sendOrderToMqtt(List<OrderEntity> changeValues) {
try {
String sendOrder = iOperationService.operationDevice(changeValues);
String name = mhConfig.getName();
// 获取mqtt操作队列(后期通过mqtt队列配置发送主题)
log.info("发送主题:{},消息:{}", name + "/" + controlTopic, sendOrder);
iMqttGatewayService.publish(name + "/" + controlTopic, sendOrder, 1);
} catch (Exception e) {
log.error("设备操作失败", e);
}
}
public void adjustWaterValve(String kp, String ki, String kd) {
// 西餐走廊2、宴会走廊需要调整PID参数,其他的ddc自己已经处理好
String[] deviceLedgerIds = new String[]{"ddc0083b3a898d85f3a1205a2d82071e100", "ddc0133b3a898d85f3a1205a2d82071e100"};
for (String deviceLedgerId : deviceLedgerIds) {
// 获取西餐走廊2的启停控制
HashMap<String, Object> queryMap = new HashMap<>();
queryMap.put("systemType", "2");
queryMap.put("deviceLedgerId", deviceLedgerId);
queryMap.put("isUse", 0);
// 得出 systemType =2 的数据
List<CollectionParamsManage> collectionParamsManages = collectionParamsManageService.selectListByParams(queryMap);
CollectionParamsManage collectionParamsManage = new CollectionParamsManage();
// 过滤得出启停状态
Optional<CollectionParamsManage> first = collectionParamsManages.stream().filter(item -> item.getCurValue().intValue() == 1 && item.getParamType().equals("2")).findFirst();
if (first.isEmpty()) {
// 如果设备停止了,则同步关掉水阀
// 过滤获取水阀调节参数
Optional<CollectionParamsManage> fourth = collectionParamsManages
.stream()
.filter(item -> item.getOtherName().contains("水阀调节")
&& item.getParamType().equals("3")).findFirst();
if (fourth.isEmpty()) {
continue;
}
// 得出水阀调节参数
collectionParamsManage = fourth.get();
// 先判断水阀是否已经关闭
if (collectionParamsManage.getCurValue().intValue() == 0) {
continue;
}
// 关闭
List<OrderEntity> changeValues = new ArrayList<>();
changeValues.add(new OrderEntity(collectionParamsManage.getId(), String.valueOf(0), Integer.parseInt(collectionParamsManage.getParamType()), collectionParamsManage.getOtherName()));
sendOrderToMqtt(changeValues);
continue;
}
// 过滤获取回风温度设置值
Optional<CollectionParamsManage> second = collectionParamsManages
.stream()
.filter(item -> item.getOtherName().contains("回风温度")
&& item.getParamType().equals("14")).findFirst();
if (second.isEmpty()) {
continue;
}
// 得出回风温度设置值
double backTempSet = second.get().getCurValue().doubleValue();
// 设定目标温度(夏季制冷24℃)
// ✅ 如果没有该设备的控制器,则创建一个新的并保存起来
FuzzyPIDControlUtil controller = pidControllers.computeIfAbsent(deviceLedgerId, k -> new FuzzyPIDControlUtil(kp, ki, kd));
log.info("开始模糊PID控制循环,查看对象是否有变化:{}", controller);
// 过滤获取当前回风温度
Optional<CollectionParamsManage> third = collectionParamsManages
.stream()
.filter(item -> item.getOtherName().contains("回风温度")
&& item.getParamType().equals("12")).findFirst();
if (third.isEmpty()) {
continue;
}
// 得出当前回风温度
double temp = third.get().getCurValue().doubleValue();
// 2. 计算水阀开度(时间间隔1秒)
double valveOpening1 = controller.calculate(backTempSet, temp, 1);
int valveOpening = new BigDecimal(valveOpening1).intValue();
// 过滤获取水阀调节参数
Optional<CollectionParamsManage> fourth = collectionParamsManages
.stream()
.filter(item -> item.getOtherName().contains("水阀调节")
&& item.getParamType().equals("3")).findFirst();
if (fourth.isEmpty()) {
continue;
}
// 得出水阀调节参数
collectionParamsManage = fourth.get();
// 发送控制指令
if (valveOpening > 0 && valveOpening <= 100) {
// 开启
List<OrderEntity> changeValues = new ArrayList<>();
changeValues.add(new OrderEntity(collectionParamsManage.getId(), String.valueOf(valveOpening), Integer.parseInt(collectionParamsManage.getParamType()), collectionParamsManage.getOtherName()));
sendOrderToMqtt(changeValues);
// 3. 应用水阀开度(实际应用发送给执行机构)
log.info("回风温度: {} ℃ | 水阀开度: {} % ",
temp, valveOpening);
}
}
}
public void startOrStopAHU() {
// 扫描启动了定时开关机的风机,根据当前时间判断是否需要启动或停止
// systemType 2: 风柜系统
HashMap<String, Object> queryMap = new HashMap<>();
queryMap.put("systemType", "2");
// 得出 systemType =2 的数据
List<CollectionParamsManage> collectionParamsManages = collectionParamsManageService.selectListByParams(queryMap);
// 判断当前时间是星期几
String dayOfWeekValue = DateUtils.dayOfWeekValue();
// 过滤otherName包含dayOfWeekValue,paramType=29, curValue=1的数据,代表已经启用定时开关机的功能
List<CollectionParamsManage> needStartOrStopDataList = collectionParamsManages
.stream()
.filter(item -> item.getOtherName().contains(dayOfWeekValue)
&& item.getParamType().equals("29")
&& item.getCurValue().intValue() == 1)
.toList();
// 查询得出对应的houseId
List<PolicyManage> policyManageList = policyManageService.selectListByCpmIds(needStartOrStopDataList);
// 开始:根据houseId查询出对应的风机启停id
List<CpmSpaceRelation> cpmSpaceRelationList = cpmSpaceRelationService.selectListByHouseId(policyManageList);
// collectionParamsManages过滤出能够开启风机的点位,paramType=2,isUse=0
List<CollectionParamsManage> startDeviceList = collectionParamsManages
.stream()
.filter(item -> item.getParamType().equals("2")
&& item.getIsUse() == 0)
.toList();
// 结束:根据houseId查询出对应的风机启停id
// 在拼接出启用定时开关机的启动时间、关闭时间
Map<String, List<PolicyManage>> groupedByHouseId = policyManageList.stream()
.collect(Collectors.groupingBy(
PolicyManage::getHouseId,
Collectors.toList()
));
// groupedByHouseId for 循环遍历
for (Map.Entry<String, List<PolicyManage>> entry : groupedByHouseId.entrySet()) {
// 得出houseId
String houseId = entry.getKey();
List<PolicyManage> timeList1 = entry.getValue();
if (timeList1.isEmpty()) {
continue;
}
PolicyManage policyManage1 = timeList1.getFirst();
// 得出policyManageList
List<PolicyManage> timeList = policyManageService.selectPolicyListByHouseId(houseId, policyManage1.getPolicyName());
int isHaveTime = 0;
int startHour = 0;
int startMinute = 0;
int endHour = 0;
int endMinute = 0;
for (PolicyManage policyManage : timeList) {
if (policyManage.getPointName().contains("开_时")) {
startHour = collectionParamsManageService.selectCollectionParamsManageById(policyManage.getCpmId()).getCurValue().intValue();
isHaveTime++;
}
if (policyManage.getPointName().contains("开_分")) {
startMinute = collectionParamsManageService.selectCollectionParamsManageById(policyManage.getCpmId()).getCurValue().intValue();
isHaveTime++;
}
if (policyManage.getPointName().contains("关_时")) {
endHour = collectionParamsManageService.selectCollectionParamsManageById(policyManage.getCpmId()).getCurValue().intValue();
isHaveTime++;
}
if (policyManage.getPointName().contains("关_分")) {
endMinute = collectionParamsManageService.selectCollectionParamsManageById(policyManage.getCpmId()).getCurValue().intValue();
isHaveTime++;
}
}
if (isHaveTime == 0) {
continue;
}
LocalTime nowTime = LocalTime.now();
LocalTime startTime = LocalTime.of(startHour, startMinute);
LocalTime endTime = LocalTime.of(endHour, endMinute);
// collectionParamsManages过滤出能够开启风机的点位,paramType=2,isUse=0
Set<String> validCpmIds = cpmSpaceRelationList.stream()
.filter(item -> item.getHouseId().equals(houseId))
.map(CpmSpaceRelation::getCpmId)
.collect(Collectors.toSet());
List<CollectionParamsManage> startDataList = startDeviceList
.stream()
.filter(item -> validCpmIds.contains(item.getId()))
.toList();
// 判断当前风机是否在开启状态了
if (null == startDataList || startDataList.size() == 0) {
return;
}
CollectionParamsManage first = startDataList.getFirst();
// 判断当前时间是否在开启时间范围内
if (DateUtils.isBetween(nowTime, startTime, endTime)) {
// 判断当前风机是否在开启状态了
if (first.getCurValue().intValue() == 1) {
// 当前风机在开启状态,不需要启动
log.info("当前风机在开启状态,不需要启动");
} else {
// 当前风机不在开启状态,需要启动
log.info("当前风机不在开启状态,需要启动");
List<OrderEntity> changeValues = new ArrayList<>();
changeValues.add(new OrderEntity(first.getId(), "1", Integer.parseInt(first.getParamType()), first.getOtherName()));
sendOrderToMqtt(changeValues);
}
;
} else {
// 判断当前风机是否在关闭状态了
if (first.getCurValue().intValue() == 0) {
// 当前风机在关闭状态,不需要停止
log.info("当前风机在关闭状态,不需要停止");
} else {
// 当前风机不在关闭状态,需要停止
log.info("当前风机不在关闭状态,需要停止");
List<OrderEntity> changeValues = new ArrayList<>();
changeValues.add(new OrderEntity(first.getId(), "0", Integer.parseInt(first.getParamType()), first.getOtherName()));
sendOrderToMqtt(changeValues);
}
}
}
}
}

206
mh-quartz/src/main/java/com/mh/quartz/task/ChillersTask.java

@ -0,0 +1,206 @@
package com.mh.quartz.task;
import com.mh.common.config.MHConfig;
import com.mh.common.core.domain.dto.DeviceMonitorDTO;
import com.mh.common.core.domain.entity.CollectionParamsManage;
import com.mh.common.core.domain.entity.CpmSpaceRelation;
import com.mh.common.core.domain.entity.OrderEntity;
import com.mh.common.core.domain.entity.PolicyManage;
import com.mh.common.utils.DateUtils;
import com.mh.common.utils.StringUtils;
import com.mh.framework.mqtt.service.IMqttGatewayService;
import com.mh.system.service.device.ICollectionParamsManageService;
import com.mh.system.service.operation.IOperationDeviceService;
import com.mh.system.service.policy.IPolicyManageService;
import com.mh.system.service.report.IReportSysService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author LJF
* @version 1.0
* @project EEMCS
* @description 冷水机组定时任务
* @date 2025-08-13 17:22:09
*/
@Slf4j
@Component("chillersTask")
public class ChillersTask {
@Value("${control.topic}")
String controlTopic;
@Autowired
private MHConfig mhConfig;
private final IReportSysService reportSysService;
private final ICollectionParamsManageService collectionParamsManageService;
private final IPolicyManageService policyManageService;
private final IOperationDeviceService iOperationService;
private final IMqttGatewayService iMqttGatewayService;
public ChillersTask(IReportSysService reportSysService,
ICollectionParamsManageService collectionParamsManageService,
IPolicyManageService policyManageService, IOperationDeviceService iOperationService, IMqttGatewayService iMqttGatewayService) {
this.reportSysService = reportSysService;
this.collectionParamsManageService = collectionParamsManageService;
this.policyManageService = policyManageService;
this.iOperationService = iOperationService;
this.iMqttGatewayService = iMqttGatewayService;
}
/**
* 创建系统运行参数
*/
public void createSysRunParam() {
// 定时执行运行脚本
reportSysService.execProSysRunParamHis();
}
/**
* 偏移值定时设置
*/
public void driftValueSet() {
// 偏移值定时设置
// systemType 0: 主机空调系统
HashMap<String, Object> queryMap = new HashMap<>();
queryMap.put("systemType", "0");
// 得出 systemType =0 的数据
List<CollectionParamsManage> collectionParamsManages = collectionParamsManageService.selectListByParams(queryMap);
List<DeviceMonitorDTO> policyManages = (List<DeviceMonitorDTO>) policyManageService.selectPolicyList("0", "4");
// 过滤otherName包含paramType=29, curValue=1,deviceLedgerId不为空的数据,代表已经启用定时开关机的功能
List<CollectionParamsManage> needStartOrStopDataList = collectionParamsManages
.stream()
.filter(item -> item.getParamType().equals("29")
&& StringUtils.isNotEmpty(item.getDeviceLedgerId())
&& item.getCurValue().intValue() == 1)
.toList();
List<PolicyManage> list = policyManageService.selectListByCpmIds(needStartOrStopDataList);
// policyManages匹配policyManageList存在的policyName
List<DeviceMonitorDTO> policyManageList = policyManages.stream()
.filter(item -> list.stream().anyMatch(policy -> policy.getPolicyName().equals(item.getName()))).toList();
// policyManageList根据policy_name进行分组,获取对应的策略数据
// Map<String, List<PolicyManage>> groupedByPolicyName = policyManageList.stream().collect(Collectors.groupingBy(
// PolicyManage::getPolicyName,
// Collectors.toList()
// ));
for (DeviceMonitorDTO value : policyManageList) {
List<PolicyManage> manageList = (List<PolicyManage>) value.getValues();
// 获取当前设置的偏移值
Optional<PolicyManage> tempSet = manageList.stream().filter(item -> item.getPointName().contains("当前偏移值设置")).findFirst();
BigDecimal curTempSetValue = new BigDecimal(0);
BigDecimal offsetValue = new BigDecimal(0);
String otherName = "";
String quality = "";
String cpmId = "";
String paramType = "";
if (tempSet.isPresent()) {
PolicyManage tempSetPolicy = tempSet.get();
// 获取collectionParamsManages中id为tempSetPolicy.getCpmId()的数据
Optional<CollectionParamsManage> tempSetCpm = collectionParamsManages.stream().filter(item -> item.getId().equals(tempSetPolicy.getCpmId())).findFirst();
if (tempSetCpm.isPresent()) {
CollectionParamsManage collectionParamsManage = tempSetCpm.get();
curTempSetValue = collectionParamsManage.getCurValue();
otherName = collectionParamsManage.getOtherName();
quality = collectionParamsManage.getQuality();
cpmId = collectionParamsManage.getId();
paramType = collectionParamsManage.getParamType();
}
}
// 获取设置值
Optional<PolicyManage> offsetValuePolicy = manageList.stream().filter(item -> item.getPointName().contains("目标偏移值")).findFirst();
if (offsetValuePolicy.isPresent()) {
PolicyManage offsetValuePm = offsetValuePolicy.get();
// 获取collectionParamsManages中id为tempSetPolicy.getCpmId()的数据
Optional<CollectionParamsManage> tempSetCpm = collectionParamsManages.stream().filter(item -> item.getId().equals(offsetValuePm.getCpmId())).findFirst();
if (tempSetCpm.isPresent()) {
CollectionParamsManage collectionParamsManage = tempSetCpm.get();
offsetValue = collectionParamsManage.getCurValue();
}
}
int isHaveTime = 0;
int startHour = 0;
int startMinute = 0;
int endHour = 0;
int endMinute = 0;
for (PolicyManage policyManage : manageList) {
if (policyManage.getPointName().contains("开时")) {
startHour = collectionParamsManageService.selectCollectionParamsManageById(policyManage.getCpmId()).getCurValue().intValue();
isHaveTime++;
}
if (policyManage.getPointName().contains("开分")) {
startMinute = collectionParamsManageService.selectCollectionParamsManageById(policyManage.getCpmId()).getCurValue().intValue();
isHaveTime++;
}
if (policyManage.getPointName().contains("关时")) {
endHour = collectionParamsManageService.selectCollectionParamsManageById(policyManage.getCpmId()).getCurValue().intValue();
isHaveTime++;
}
if (policyManage.getPointName().contains("关分")) {
endMinute = collectionParamsManageService.selectCollectionParamsManageById(policyManage.getCpmId()).getCurValue().intValue();
isHaveTime++;
}
}
if (isHaveTime == 0) {
continue;
}
LocalTime nowTime = LocalTime.now();
LocalTime startTime = LocalTime.of(startHour, startMinute);
LocalTime endTime = LocalTime.of(endHour, endMinute);
// 判断当前时间是否在开启时间范围内
if (DateUtils.isBetween(nowTime, startTime, endTime)) {
// 判断当前通信是否正常,并且设置值跟偏移值是否一样
if (quality.equals("0") && curTempSetValue.compareTo(offsetValue) == 0) {
// 当前风机不在开启状态,需要启动
log.info("当前偏移值相等,不需要在设置");
} else if (quality.equals("0") && curTempSetValue.compareTo(offsetValue) != 0) {
if (StringUtils.isNotEmpty(cpmId) && StringUtils.isNotEmpty(otherName)) {
List<OrderEntity> changeValues = new ArrayList<>();
changeValues.add(new OrderEntity(cpmId, String.valueOf(offsetValue.intValue()), Integer.parseInt(paramType), otherName));
sendOrderToMqtt(changeValues);
}
}
} else {
// 判断当前风机是否在关闭状态了
if (curTempSetValue.intValue() == 0) {
// 当前偏移值等于0,不需要在设置
log.info("当前偏移值等于0,不需要在设置");
} else {
// 当前偏移值不等于0,不需要在设置
log.info("当前偏移值不等于0,需要在设置");
List<OrderEntity> changeValues = new ArrayList<>();
changeValues.add(new OrderEntity(cpmId, "0", Integer.parseInt(paramType), otherName));
sendOrderToMqtt(changeValues);
}
}
}
}
public void sendOrderToMqtt(List<OrderEntity> changeValues) {
try {
String sendOrder = iOperationService.operationDevice(changeValues);
String name = mhConfig.getName();
// 获取mqtt操作队列(后期通过mqtt队列配置发送主题)
log.info("发送主题:{},消息:{}", name + "/" + controlTopic, sendOrder);
iMqttGatewayService.publish(name + "/" + controlTopic, sendOrder, 1);
} catch (Exception e) {
log.error("设备操作失败", e);
}
}
}

84
mh-quartz/src/main/java/com/mh/quartz/task/CreateAlarmTask.java

@ -6,18 +6,21 @@ import com.mh.common.core.domain.entity.AlarmRules;
import com.mh.common.core.domain.entity.CollectionParamsManage; import com.mh.common.core.domain.entity.CollectionParamsManage;
import com.mh.common.utils.BigDecimalUtils; import com.mh.common.utils.BigDecimalUtils;
import com.mh.common.utils.DateUtils; import com.mh.common.utils.DateUtils;
import com.mh.framework.rabbitmq.producer.SendMsgByTopic;
import com.mh.system.service.device.ICollectionParamsManageService; import com.mh.system.service.device.ICollectionParamsManageService;
import com.mh.system.service.operation.IAlarmCodeService; import com.mh.system.service.operation.IAlarmCodeService;
import com.mh.system.service.operation.IAlarmRecordsService; import com.mh.system.service.operation.IAlarmRecordsService;
import com.mh.system.service.operation.IAlarmRulesService; import com.mh.system.service.operation.IAlarmRulesService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit;
/** /**
@ -31,81 +34,32 @@ import java.util.List;
@Component("createAlarmTask") @Component("createAlarmTask")
public class CreateAlarmTask { public class CreateAlarmTask {
private final IAlarmRulesService alarmRulesService;
private final IAlarmCodeService alarmCodeService;
private final ICollectionParamsManageService collectionParamsManageService;
private final IAlarmRecordsService alarmRecordService; private final IAlarmRecordsService alarmRecordService;
private final SendMsgByTopic sendMsgByTopic;
@Autowired @Autowired
public CreateAlarmTask(IAlarmRulesService alarmRulesService, IAlarmCodeService alarmCodeService, ICollectionParamsManageService collectionParamsManageService, IAlarmRecordsService alarmRecordService) { public CreateAlarmTask(IAlarmRecordsService alarmRecordService, SendMsgByTopic sendMsgByTopic) {
this.alarmRulesService = alarmRulesService;
this.alarmCodeService = alarmCodeService;
this.collectionParamsManageService = collectionParamsManageService;
this.alarmRecordService = alarmRecordService; this.alarmRecordService = alarmRecordService;
this.sendMsgByTopic = sendMsgByTopic;
} }
public void createAlarmTask() { public void createAlarmTask() {
// log.info("创建报警记录"); log.info("创建报警记录");
// 查询仪表报警规则记录,查看哪些规则启用了 // 第一次判断
List<AlarmRules> alarmRules = alarmRulesService.selectAlarmRulesListByStatus(0); String alarmTask = alarmRecordService.createAlarmTask();
// 循环查询报警规则,判断是否满足报警条件 if (null == alarmTask) {
for (AlarmRules alarmRule : alarmRules) { return;
// 判断报警类型
if ("0".equals(alarmRule.getAlarmType())) {
// 当前是越限事件
// 查询事件类型查询对应的报警模板内容
AlarmCode alarmCode = alarmCodeService.selectAlarmCodeByAlarmType(alarmRule.getEventType());
// 获取当前采集参数值
CollectionParamsManage collectionParamsManage = collectionParamsManageService.selectCollectionParamsManageById(alarmRule.getCpmId());
// 判断当前值是否是当前事件
AlarmRecords alarmRecords = new AlarmRecords();
BigDecimal curValue = collectionParamsManage.getCurValue();
Date curTime = collectionParamsManage.getCurTime();
// 阈值
String threshold1 = alarmRule.getThreshold1();
if (alarmRule.getTimePeriodSet() == 0 && DateUtils.isSameDay(curTime, new Date())) {
// 执行相关操作
insertOrUpdateRecord(alarmRule, curValue, threshold1, alarmCode, alarmRecords, collectionParamsManage);
} else if (alarmRule.getTimePeriodSet() == 1
&& DateUtils.isSameDay(collectionParamsManage.getCurTime(), new Date())
&& DateUtils.isCurrentTimeInRange(alarmRule.getBeginTime(), alarmRule.getEndTime(), curTime)
) {
// 执行相关操作
insertOrUpdateRecord(alarmRule, curValue, threshold1, alarmCode, alarmRecords, collectionParamsManage);
}
}
} }
} // 根据","逗号进行分割
String[] alarmTaskArray = alarmTask.split(",");
private void insertOrUpdateRecord(AlarmRules alarmRule, BigDecimal curValue, String threshold1, AlarmCode alarmCode, AlarmRecords alarmRecords, CollectionParamsManage collectionParamsManage) { // 遍历
boolean compare = BigDecimalUtils.compare(alarmRule.getCondition1(), curValue, new BigDecimal(threshold1)); for (String id : alarmTaskArray) {
if (compare) { if (null == id || id.isEmpty()) {
// 创建报警记录 continue;
String content = alarmCode.getMsgContent();
content = content.replace("#{curValue}", curValue.setScale(1, RoundingMode.HALF_UP).toString());
content = content.replace("#{setValue}", alarmRule.getCondition1() + threshold1);
alarmRecords.setContent(content);
alarmRecords.setAlarmType(alarmRule.getAlarmType());
alarmRecords.setEventType(alarmRule.getEventType());
alarmRecords.setAlarmLevel(alarmRule.getAlarmLevel());
alarmRecords.setLedgerId(alarmRule.getLedgerId());
alarmRecords.setCpmId(alarmRule.getCpmId());
alarmRecords.setDeviceName(alarmRule.getDeviceName());
alarmRecords.setCpmName(alarmRule.getCpmName());
alarmRecords.setCreateTime(collectionParamsManage.getCurTime());
// 判断报警记录是否已经存在
AlarmRecords isExits = alarmRecordService.selectIsExist(alarmRecords);
if (isExits == null) {
alarmRecordService.insertAlarmRecord(alarmRecords);
} else {
// 更新报警记录
isExits.setContent(content);
isExits.setCreateTime(collectionParamsManage.getCurTime());
alarmRecordService.updateAlarmRecord(isExits);
} }
sendMsgByTopic.sendDelayedAlarm(id, 1);
} }
} }

42
mh-quartz/src/main/java/com/mh/quartz/task/DealDataTask.java

@ -6,6 +6,7 @@ import com.mh.common.core.domain.entity.DeviceReport;
import com.mh.common.core.redis.RedisCache; import com.mh.common.core.redis.RedisCache;
import com.mh.common.enums.ComputeEnum; import com.mh.common.enums.ComputeEnum;
import com.mh.common.utils.DateUtils; import com.mh.common.utils.DateUtils;
import com.mh.common.utils.StringUtils;
import com.mh.framework.dealdata.DataProcessService; import com.mh.framework.dealdata.DataProcessService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -114,7 +115,10 @@ public class DealDataTask {
int ratio = entity.getMtRatio(); int ratio = entity.getMtRatio();
if (ObjectUtils.isEmpty(lastData) || ObjectUtils.isEmpty(lastData.getLastValue())) { if (ObjectUtils.isEmpty(lastData) || ObjectUtils.isEmpty(lastData.getLastValue())) {
//从device_manage取出初始值 //从device_manage取出初始值
String initValue = dataProcessService.queryInitValue(entity.getMtNum()); String initValue = dataProcessService.queryInitValue(entity.getMtNum(), entity.getMtCode(), entity.getRegisterAddr());
if (StringUtils.isEmpty(initValue)) {
initValue = "0";
}
DeviceReport firstEntity = new DeviceReport(); DeviceReport firstEntity = new DeviceReport();
firstEntity.setLastValue(initValue); firstEntity.setLastValue(initValue);
firstEntity.setLastTime(entity.getCurTime()); firstEntity.setLastTime(entity.getCurTime());
@ -126,7 +130,12 @@ public class DealDataTask {
firstEntity.setRegisterAddr(entity.getRegisterAddr()); firstEntity.setRegisterAddr(entity.getRegisterAddr());
firstEntity.setDeviceType(deviceType); firstEntity.setDeviceType(deviceType);
firstEntity.setRatio(ratio); firstEntity.setRatio(ratio);
double usedValue = entity.getCurValue().doubleValue() - Double.parseDouble(initValue); double usedValue = 0;
try {
usedValue = entity.getCurValue().doubleValue() - Double.parseDouble(initValue);
} catch (NumberFormatException e) {
log.error("数值格式解析异常:{}", e);
}
firstEntity.setUsedValue(String.valueOf(usedValue)); firstEntity.setUsedValue(String.valueOf(usedValue));
//区分瞬时值 //区分瞬时值
if ((deviceGrade >= 100 && deviceGrade < 200) || (deviceGrade >= 1200 && deviceGrade < 1300) ) { if ((deviceGrade >= 100 && deviceGrade < 200) || (deviceGrade >= 1200 && deviceGrade < 1300) ) {
@ -198,6 +207,7 @@ public class DealDataTask {
} }
temp.setDeviceType(deviceType); temp.setDeviceType(deviceType);
temp.setRatio(ratio); temp.setRatio(ratio);
temp.setRegisterAddr(dataI.getRegisterAddr());
dataMinList.add(temp); dataMinList.add(temp);
i++; i++;
j++; j++;
@ -272,7 +282,7 @@ public class DealDataTask {
.sorted(Comparator.comparing(temMap -> temMap.keySet().iterator().next())) .sorted(Comparator.comparing(temMap -> temMap.keySet().iterator().next()))
.collect(Collectors.toList()); .collect(Collectors.toList());
//计算上次值,当前值 //计算上次值,当前值
// // log.info("计算小时表数据:{}", sortedList); log.info("计算小时表数据:{}", sortedList);
hourList = calcListData(hourList, key, "hour", sortedList); hourList = calcListData(hourList, key, "hour", sortedList);
} }
//批量插入小时报表 //批量插入小时报表
@ -315,7 +325,10 @@ public class DealDataTask {
DeviceReport hourEntity = dataProcessService.queryLastValue(key, tableType); DeviceReport hourEntity = dataProcessService.queryLastValue(key, tableType);
if (ObjectUtils.isEmpty(hourEntity)) { if (ObjectUtils.isEmpty(hourEntity)) {
//查询设备信息初始值 //查询设备信息初始值
lastValue = dataProcessService.queryInitValue(key); lastValue = dataProcessService.queryInitValue(key, null, null);
if (StringUtils.isEmpty(lastValue)) {
lastValue = "0";
}
} else { } else {
lastValue = hourEntity.getLastValue(); lastValue = hourEntity.getLastValue();
lastDate = hourEntity.getLastTime(); lastDate = hourEntity.getLastTime();
@ -493,7 +506,7 @@ public class DealDataTask {
DeviceReport entity = deviceList.get(i); DeviceReport entity = deviceList.get(i);
DeviceReport lastEntity = dataProcessService.queryLastValue(deviceNum, "month"); DeviceReport lastEntity = dataProcessService.queryLastValue(deviceNum, "month");
if (ObjectUtils.isEmpty(lastEntity)) { if (ObjectUtils.isEmpty(lastEntity)) {
lastValue = dataProcessService.queryInitValue(deviceNum); lastValue = dataProcessService.queryInitValue(deviceNum, null, null);
lastTime = entity.getCurTime(); lastTime = entity.getCurTime();
} else { } else {
lastValue = lastEntity.getLastValue(); lastValue = lastEntity.getLastValue();
@ -631,6 +644,25 @@ public class DealDataTask {
} }
} }
/**
* 处理锅炉数据获取进入chillers表
*/
public void dealBoilerData() {
List<CollectionParamsManage> cacheList = redisCache.getCacheList(Constants.BOILER, CollectionParamsManage.class);
if (null == cacheList || cacheList.isEmpty()) {
return;
}
//清空redis
redisCache.deleteObject(Constants.BOILER);
//处理chillers数据
try {
//todo 处理没有对象curValue和curTime的异常
dealChillersCollect(cacheList);
} catch (Exception e) {
log.error("处理主机参数异常:{}", e);
}
}
/** /**
* 处理主机秒级数据再计算主机运行时间 * 处理主机秒级数据再计算主机运行时间
* *

2
mh-quartz/src/main/java/com/mh/quartz/task/DealOnOrOffData.java

@ -22,7 +22,7 @@ public class DealOnOrOffData {
} }
public void dealDeviceLedger() { public void dealDeviceLedger() {
// log.info("处理设备在线状态数据"); log.info("处理设备在线状态数据");
deviceLedgerService.updateDeviceLedgerStatus(); deviceLedgerService.updateDeviceLedgerStatus();
} }

72
mh-quartz/src/main/java/com/mh/quartz/task/GGDataTask.java

@ -1,72 +0,0 @@
package com.mh.quartz.task;
import com.mh.common.core.domain.entity.WeatherData;
import com.mh.common.utils.WeatherUtil;
import com.mh.system.service.IWeatherDataService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
/**
* @author LJF
* @version 1.0
* @project EEMCS
* @description 广工需要的数据计算
* @date 2026-04-21 19:05:21
*/
@Slf4j
@Component("ahuTask")
public class GGDataTask {
@Autowired
private IWeatherDataService weatherDataService;
public void calcWeatherData() {
// 从天气预报保存的表中获取没有焓值的数据
WeatherUtil weatherUtil = new WeatherUtil();
List<WeatherData> weatherDataList = weatherDataService.selectByEnthalpyEtc();
if (weatherDataList != null && !weatherDataList.isEmpty()) {
// 室外压力,采用标准大气压 101325 Pa
String pressure = "101.325";
for (WeatherData weatherData : weatherDataList) {
// 室外温度
int temperature = weatherData.getTemperature();
// 室外湿度
int humidity = weatherData.getHumidity();
// 室外含湿
String wet = String.valueOf(new BigDecimal(humidity).divide(new BigDecimal("100")).setScale(1, RoundingMode.HALF_UP));
BigDecimal humidityRatio = weatherUtil.returnMoistureContent(String.valueOf(temperature),
wet,
pressure);
weatherData.setHumidityContent(humidityRatio.setScale(1, RoundingMode.HALF_UP).doubleValue());
// 室外焓值
BigDecimal enthalpy = weatherUtil.returnEnthalpy(String.valueOf(temperature),
wet,
pressure);
weatherData.setEnthalpy(enthalpy.setScale(1, RoundingMode.HALF_UP).doubleValue());
// 室外露点温度
BigDecimal dewPointTemp = weatherUtil.calculateDewPoint(temperature, humidity);
weatherData.setDewPointTemp(dewPointTemp.setScale(1, RoundingMode.HALF_UP).doubleValue());
// 室外湿球温度
BigDecimal wetBulbTemp = weatherUtil.returnComputePsi(temperature, (double) humidity / 100, Double.parseDouble(pressure) * 1000);
weatherData.setWetBulbTemp(wetBulbTemp.setScale(1, RoundingMode.HALF_UP).doubleValue());
try {
weatherDataService.updateDataById(weatherData);
} catch (Exception e) {
log.error("更新天气数据失败:{}", e.getMessage());
}
}
}
}
}

38
mh-quartz/src/main/java/com/mh/quartz/task/HomeTask.java

@ -0,0 +1,38 @@
package com.mh.quartz.task;
import com.mh.common.constant.CacheConstants;
import com.mh.common.core.redis.RedisCache;
import com.mh.system.service.overview.IProOverviewService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* @author LJF
* @version 1.0
* @project EEMCS
* @description 首页任务
* @date 2025-12-24 09:04:57
*/
@Slf4j
@Component("homeTask")
public class HomeTask {
@Autowired
private IProOverviewService proOverviewService;
@Autowired
private RedisCache redisCache;
public void updateHomeData() {
if (redisCache.hasKey(CacheConstants.PRO_PROFILE)) {
redisCache.deleteObject(CacheConstants.PRO_PROFILE);
}
proOverviewService.getProProfile();
if (redisCache.hasKey(CacheConstants.ENERGY_ANALYSIS)) {
redisCache.deleteObject(CacheConstants.ENERGY_ANALYSIS);
}
proOverviewService.energyAnalysis();
}
}

4
mh-quartz/src/main/java/com/mh/quartz/task/HotWaterTask.java

@ -180,7 +180,7 @@ public class HotWaterTask {
*/ */
public void calcEnergyDataDetail(String lastHourTime) { public void calcEnergyDataDetail(String lastHourTime) {
//TODO 1、查询sql获取对应计算的楼层id、楼层名称用来当作楼栋id和楼栋名称 //TODO 1、查询sql获取对应计算的楼层id、楼层名称用来当作楼栋id和楼栋名称
List<Map<String, Object>> floorInfos = energyQueryService.queryFloorInfo(); List<Map<String, Object>> floorInfos = energyQueryService.queryFloorInfo("1");
// 开始遍历 // 开始遍历
if (StringUtils.isEmpty(lastHourTime)) { if (StringUtils.isEmpty(lastHourTime)) {
LocalDateTime now = LocalDateTime.now(); LocalDateTime now = LocalDateTime.now();
@ -276,7 +276,7 @@ public class HotWaterTask {
specificConsumption = water > 0 ? electricity / water : 0.0; specificConsumption = water > 0 ? electricity / water : 0.0;
// log.info("楼栋: {}, {}电表总量: {}, 水表总量: {}, 单耗: {}", buildingName, energyType, electricity, water, specificConsumption); log.info("楼栋: {}, {}电表总量: {}, 水表总量: {}, 单耗: {}", buildingName, energyType, electricity, water, specificConsumption);
} }
energyQueryService.insertOrUpdateEnergyData( energyQueryService.insertOrUpdateEnergyData(
energyType.getCode(), buildingId, buildingName, curDate, energyType.getCode(), buildingId, buildingName, curDate,

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save