Compare commits

..

45 Commits
master ... dev

Author SHA1 Message Date
v-lijf43 f555c156c9 修复楼栋添加 3 days ago
mh f5a1d1b698 1、对接海尔热泵 1 week ago
mh 3fe22641d6 1、放开定时任务处理 3 weeks ago
mh 6ccc5be414 1、楼栋管理添加高低区域水箱高度设置; 3 months ago
mh 66c0b8f899 1、知识库管理 3 months ago
mh c95c8ebc21 1、知识库管理 3 months ago
mh b174d79fe5 1、优化预测出现null 3 months ago
mh 2b3b9fbdd5 1、优化预测出现null 3 months ago
mh 659913fd1d 1、修复水表校验 4 months ago
mh b298be7fd9 1、美的泵读取设置问题修复; 4 months ago
mh d93f91037c 1、excel导入异常,pom版本导致 4 months ago
mh 6fa9ab3f7e 1、分析查询添加使用时间; 4 months ago
mh 0023e82d89 1、用能预测后端数据处理; 4 months ago
mh 8d77490a9f 1、用能预测后端数据处理; 4 months ago
mh 6e23904902 1、用能预测后端数据处理; 4 months ago
mh f0719ee78d 1、添加BP神经网络预测算法 5 months ago
mh 7fc0d63d6f 1、压变水位读取更新sql修复; 5 months ago
mh 9b92196e9c 1、水位设置bug修复 6 months ago
mh dd2a9e984d 1、状态检测报文异常处理 6 months ago
mh 7af983ebad 1、优化水位解析 6 months ago
mh b819375d55 1、优化能耗分析 6 months ago
mh 0127b2122f 1、优化能耗分析 6 months ago
mh fc890b53e0 1、修改成工厂模式+策略模式进行数据采集发送解析;2、兼容jdk17 6 months ago
mh 11fae3d85c 修改成工厂模式+策略模式进行数据采集发送解析 6 months ago
mh c331d15b35 1、IEEE754浮点型优化; 6 months ago
mh 0efc951fa7 1、代码优化;2、楼栋编辑增加热泵个数参数; 6 months ago
mh 3adb86d86f 1、代码优化;2、楼栋编辑增加热泵个数参数; 6 months ago
mh c2fdcf763d 1、代码优化 7 months ago
mh f436d1690b 1、根据项目计算水位或者数据;2、修改日志插入死锁; 7 months ago
mh d8abc75341 1、分批次执行线程; 7 months ago
mh c795ac7737 1、修改单抄响应报文;2、分批次执行线程; 7 months ago
mh 75aeaa8a12 1、线程开启根据端口号进行分配; 8 months ago
mh 6aa5718d6a 1、设备更换,优化采集指令动态生成;2、定时采集动态获取对应的线程数 8 months ago
mh 19248479eb 1、设备更换,动态添加采集指令以及增加校验位;2、增加时控校验;3、增加瑞星热泵时钟校验; 8 months ago
mh d3c672b64d 采集参数优化 9 months ago
mh 4f478a504d 设备控制代码整理优化 9 months ago
mh 6657e8ffeb 设备控制代码整理 9 months ago
mh b80e47e541 添加校准和多个水位控制 9 months ago
mh d3d970768a 优化采集控制逻辑 10 months ago
mh faa17b1a93 优化采集控制逻辑 10 months ago
mh 5d6b9c58b2 优化采集控制逻辑 10 months ago
mh b2e336d43f 优化采集控制逻辑 11 months ago
mh db2f64cd54 优化采集逻辑 11 months ago
mh 40f7577927 优化采集结构 11 months ago
mh 19dbbb5c81 优化采集结构 11 months ago
  1. 199
      2024数据库脚本.sql
  2. 135
      algorithm/pom.xml
  3. 8
      algorithm/src/main/java/com/mh/algorithm/bpnn/ActivationFunction.java
  4. 111
      algorithm/src/main/java/com/mh/algorithm/bpnn/BPModel.java
  5. 262
      algorithm/src/main/java/com/mh/algorithm/bpnn/BPNeuralNetworkFactory.java
  6. 106
      algorithm/src/main/java/com/mh/algorithm/bpnn/BPParameter.java
  7. 15
      algorithm/src/main/java/com/mh/algorithm/bpnn/Sigmoid.java
  8. 24
      algorithm/src/main/java/com/mh/algorithm/constants/OrderEnum.java
  9. 88
      algorithm/src/main/java/com/mh/algorithm/knn/KNN.java
  10. 646
      algorithm/src/main/java/com/mh/algorithm/matrix/Matrix.java
  11. 53
      algorithm/src/main/java/com/mh/algorithm/utils/CsvInfo.java
  12. 66
      algorithm/src/main/java/com/mh/algorithm/utils/CsvUtil.java
  13. 20
      algorithm/src/main/java/com/mh/algorithm/utils/DoubleUtil.java
  14. 297
      algorithm/src/main/java/com/mh/algorithm/utils/MatrixUtil.java
  15. 32
      algorithm/src/main/java/com/mh/algorithm/utils/SerializationUtil.java
  16. 71
      algorithm/src/test/java/com/mh/algorithm/bpnn/bpnnTest.java
  17. 46
      algorithm/src/test/java/com/mh/algorithm/knn/knnTest.java
  18. 26
      common/pom.xml
  19. 26
      common/src/main/java/com/mh/common/annotation/SysLogger.java
  20. 84
      common/src/main/java/com/mh/common/utils/FileUtils.java
  21. 28
      pom.xml
  22. 86
      user-service/pom.xml
  23. 3
      user-service/src/main/java/com/mh/user/UserServiceApplication.java
  24. 182
      user-service/src/main/java/com/mh/user/aspect/DaoAspect.java
  25. 2
      user-service/src/main/java/com/mh/user/aspect/SysLogAspect.java
  26. 59
      user-service/src/main/java/com/mh/user/config/CaffeineCacheConfig.java
  27. 1
      user-service/src/main/java/com/mh/user/config/QuartzConfig.java
  28. 12
      user-service/src/main/java/com/mh/user/config/RestTemplateConfig.java
  29. 47
      user-service/src/main/java/com/mh/user/constants/Constant.java
  30. 59
      user-service/src/main/java/com/mh/user/constants/DeviceEnum.java
  31. 59
      user-service/src/main/java/com/mh/user/constants/DeviceStrategyEnum.java
  32. 2
      user-service/src/main/java/com/mh/user/controller/AnalysisController.java
  33. 26
      user-service/src/main/java/com/mh/user/controller/BuildingController.java
  34. 6
      user-service/src/main/java/com/mh/user/controller/ControlSetController.java
  35. 8
      user-service/src/main/java/com/mh/user/controller/DeviceFloorController.java
  36. 32
      user-service/src/main/java/com/mh/user/controller/DeviceInstallController.java
  37. 94
      user-service/src/main/java/com/mh/user/controller/DeviceOperateController.java
  38. 36
      user-service/src/main/java/com/mh/user/controller/EnergyPreController.java
  39. 63
      user-service/src/main/java/com/mh/user/controller/KnowledgeDataController.java
  40. 627
      user-service/src/main/java/com/mh/user/controller/SerialPortController.java
  41. 85
      user-service/src/main/java/com/mh/user/controller/TestController.java
  42. 27
      user-service/src/main/java/com/mh/user/dto/EnergyPreDTO.java
  43. 37
      user-service/src/main/java/com/mh/user/dto/EnergyPreEchartDataDTO.java
  44. 37
      user-service/src/main/java/com/mh/user/dto/EnergyPreTopDataDTO.java
  45. 2
      user-service/src/main/java/com/mh/user/entity/BuildingEntity.java
  46. 5
      user-service/src/main/java/com/mh/user/entity/DeviceCodeParamEntity.java
  47. 7
      user-service/src/main/java/com/mh/user/entity/DeviceInstallEntity.java
  48. 168
      user-service/src/main/java/com/mh/user/entity/HistoryDataPre.java
  49. 38
      user-service/src/main/java/com/mh/user/entity/KnowledgeDataEntity.java
  50. 1
      user-service/src/main/java/com/mh/user/entity/MaintainInfoEntity.java
  51. 1
      user-service/src/main/java/com/mh/user/entity/SysParamEntity.java
  52. 2
      user-service/src/main/java/com/mh/user/entity/WaterLevelEntity.java
  53. 4
      user-service/src/main/java/com/mh/user/entity/WaterTempEntity.java
  54. 20
      user-service/src/main/java/com/mh/user/factory/Device.java
  55. 20
      user-service/src/main/java/com/mh/user/factory/DeviceFactory.java
  56. 46
      user-service/src/main/java/com/mh/user/factory/EleMeter.java
  57. 43
      user-service/src/main/java/com/mh/user/factory/HeatPump.java
  58. 43
      user-service/src/main/java/com/mh/user/factory/HeatPumpStatus.java
  59. 43
      user-service/src/main/java/com/mh/user/factory/PressureTrans.java
  60. 47
      user-service/src/main/java/com/mh/user/factory/StatusCheck.java
  61. 43
      user-service/src/main/java/com/mh/user/factory/TempControl.java
  62. 43
      user-service/src/main/java/com/mh/user/factory/TempTrans.java
  63. 43
      user-service/src/main/java/com/mh/user/factory/TimeControl.java
  64. 43
      user-service/src/main/java/com/mh/user/factory/WaterLevelSwitch.java
  65. 47
      user-service/src/main/java/com/mh/user/factory/WtMeter.java
  66. 87
      user-service/src/main/java/com/mh/user/job/CollectionLoopRunner.java
  67. 194
      user-service/src/main/java/com/mh/user/job/DealDataJob.java
  68. 64
      user-service/src/main/java/com/mh/user/job/GetWeatherInfoJob.java
  69. 41
      user-service/src/main/java/com/mh/user/job/JobCloud.java
  70. 39
      user-service/src/main/java/com/mh/user/job/JobMeter.java
  71. 32
      user-service/src/main/java/com/mh/user/job/JobTest.java
  72. 32
      user-service/src/main/java/com/mh/user/job/JobTest1.java
  73. 190
      user-service/src/main/java/com/mh/user/job/SendMeterWaterJob.java
  74. 7
      user-service/src/main/java/com/mh/user/mapper/AnalysisMapper.java
  75. 16
      user-service/src/main/java/com/mh/user/mapper/BuildingMapper.java
  76. 19
      user-service/src/main/java/com/mh/user/mapper/ControlSetMapper.java
  77. 2
      user-service/src/main/java/com/mh/user/mapper/DealDataMapper.java
  78. 54
      user-service/src/main/java/com/mh/user/mapper/DeviceCodeParamMapper.java
  79. 35
      user-service/src/main/java/com/mh/user/mapper/DeviceInstallMapper.java
  80. 227
      user-service/src/main/java/com/mh/user/mapper/HistoryDataPreMapper.java
  81. 57
      user-service/src/main/java/com/mh/user/mapper/KnowledgeDataMapper.java
  82. 8
      user-service/src/main/java/com/mh/user/mapper/MaintainInfoMapper.java
  83. 77
      user-service/src/main/java/com/mh/user/mapper/NowDataMapper.java
  84. 10
      user-service/src/main/java/com/mh/user/mapper/NowPublicDataMapper.java
  85. 20
      user-service/src/main/java/com/mh/user/mapper/SysParamMapper.java
  86. 12
      user-service/src/main/java/com/mh/user/mapper/provider/NowDataProvider.java
  87. 2
      user-service/src/main/java/com/mh/user/mapper/provider/SysLogProvider.java
  88. 20
      user-service/src/main/java/com/mh/user/model/SerialPortModel.java
  89. 98
      user-service/src/main/java/com/mh/user/netty/NettyChillerControlClient.java
  90. 311
      user-service/src/main/java/com/mh/user/netty/NettyChillerControlHandler.java
  91. 90
      user-service/src/main/java/com/mh/user/netty/NettyClient.java
  92. 295
      user-service/src/main/java/com/mh/user/netty/NettyClientHandler.java
  93. 179
      user-service/src/main/java/com/mh/user/netty/NettyEchoServer.java
  94. 97
      user-service/src/main/java/com/mh/user/netty/NettyMeterAndCloudClient.java
  95. 193
      user-service/src/main/java/com/mh/user/netty/NettyMeterAndCloudClientHandler.java
  96. 96
      user-service/src/main/java/com/mh/user/netty/NettyMeterClient.java
  97. 143
      user-service/src/main/java/com/mh/user/netty/NettyMeterClientHandler.java
  98. 259
      user-service/src/main/java/com/mh/user/netty/NettyMeterClientHandler1.java
  99. 215
      user-service/src/main/java/com/mh/user/serialport/SendAndReceiveByCom.java
  100. 306
      user-service/src/main/java/com/mh/user/serialport/SerialPortSendReceive.java
  101. Some files were not shown because too many files have changed in this diff Show More

199
2024数据库脚本.sql

@ -0,0 +1,199 @@
-- 2024-05-07 维修表缺少字段
ALTER TABLE maintain_info
ADD cost numeric(2, 0) NULL;
EXEC sys.sp_addextendedproperty 'MS_Description', N'材料费用', 'schema', N'dbo', 'table', N'maintain_info', 'column', N'cost';
ALTER TABLE maintain_info
ADD contents varchar(100) NULL;
EXEC sys.sp_addextendedproperty 'MS_Description', N'维保内容', 'schema', N'dbo', 'table', N'maintain_info', 'column', N'contents';
ALTER TABLE maintain_info
ADD evaluate varchar(10) NULL;
EXEC sys.sp_addextendedproperty 'MS_Description', N'评价内容', 'schema', N'dbo', 'table', N'maintain_info', 'column', N'evaluate';
-- 训练集合:
begin tran
insert into history_data_pre(cur_date,building_id,water_value,elect_value,water_level,env_min_temp,env_max_temp)
select eds.cur_date,
eds.building_id,
isnull(eds.water_value,
0) as water_value,
isnull(eds.elect_value,
0) as elect_value,
isnull(convert(numeric (24, 2), t1.water_level),
0) as water_level,
th.tempmin,
th.tempmax
from energy_day_sum eds
left join (select convert(date,
cur_date) as cur_date,
building_id,
avg(isnull(convert(numeric (24, 2), water_level), 0)) as water_level
from history_data
group by convert(date,
cur_date),
building_id) t1 on
eds.cur_date = t1.cur_date and eds.building_id = t1.building_id
left join temp_history th
on eds.cur_date = th.cur_date
where eds.building_id != '所有'
order by
eds.building_id,
eds.cur_date
rollback
-- 2024-05-09 创建历史预测表
-- 历史水电用量以及预测值
CREATE TABLE history_data_pre
(
cur_date date NULL,
building_id varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
env_min_temp numeric(24, 2) NULL,
env_max_temp numeric(24, 2) NULL,
water_value numeric(24, 2) NULL,
elect_value numeric(24, 2) NULL,
water_level numeric(24, 2) NULL,
id bigint IDENTITY(1,1) NOT NULL,
water_value_pre numeric(24, 2) NULL,
elect_value_pre numeric(24, 2) NULL,
water_level_pre numeric(24, 2) NULL,
remark varchar(200) COLLATE Chinese_PRC_CI_AS NULL,
CONSTRAINT PK_history_data_pre PRIMARY KEY (id)
);
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'历史水电用量以及预测值', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'history_data_pre';
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'日期', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'history_data_pre', @level2type=N'Column', @level2name=N'cur_date';
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'楼栋编号', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'history_data_pre', @level2type=N'Column', @level2name=N'building_id';
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'环境最低温度', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'history_data_pre', @level2type=N'Column', @level2name=N'env_min_temp';
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'环境最高温度', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'history_data_pre', @level2type=N'Column', @level2name=N'env_max_temp';
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'实际用水量', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'history_data_pre', @level2type=N'Column', @level2name=N'water_value';
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'实际用电量', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'history_data_pre', @level2type=N'Column', @level2name=N'elect_value';
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'平均水位', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'history_data_pre', @level2type=N'Column', @level2name=N'water_level';
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'id', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'history_data_pre', @level2type=N'Column', @level2name=N'id';
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'用水量预测值', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'history_data_pre', @level2type=N'Column', @level2name=N'water_value_pre';
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'用电量预测值', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'history_data_pre', @level2type=N'Column', @level2name=N'elect_value_pre';
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'平均水位预测值', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'history_data_pre', @level2type=N'Column', @level2name=N'water_level_pre';
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'备注', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'history_data_pre', @level2type=N'Column', @level2name=N'remark';
create index history_data_pre_building_id on history_data_pre (building_id);
create index history_data_pre_cur_date on history_data_pre (cur_date);
-- 2024-05-09 系统参数表增加天气区域
ALTER TABLE SysParam
ADD proArea varchar(100) NULL;
EXEC sp_addextendedproperty 'MS_Description', N'天气区域', 'schema', N'dbo', 'table', N'SysParam', 'column', N'proArea';
-- 2024-05-15 热泵使用时间表(月表)
CREATE TABLE analysis_runtime_month (
id bigint IDENTITY(1,1) NOT NULL,
cur_date varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
item_type varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
day01 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
day02 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
day03 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
day04 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
day05 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
day06 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
day07 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
day08 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
day09 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
day10 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
day11 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
day12 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
day13 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
day14 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
day15 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
day16 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
day17 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
day18 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
day19 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
day20 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
day21 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
day22 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
day23 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
day24 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
day25 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
day26 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
day27 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
day28 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
day29 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
day30 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
day31 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
total_value varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
building_id varchar(50) COLLATE Chinese_PRC_CI_AS NULL
);
-- 使用时间年表
CREATE TABLE analysis_runtime_year (
id bigint IDENTITY(1,1) NOT NULL,
cur_date varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
item_type varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
month01 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
month02 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
month03 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
month04 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
month05 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
month06 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
month07 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
month08 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
month09 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
month10 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
month11 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
month12 varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
total_value varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
building_id varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
building_name varchar(50) COLLATE Chinese_PRC_CI_AS NULL,
CONSTRAINT analysis_runtime_year_id PRIMARY KEY (id)
);
-- Extended properties
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'序号', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'analysis_runtime_year', @level2type=N'Column', @level2name=N'id';
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'日期', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'analysis_runtime_year', @level2type=N'Column', @level2name=N'cur_date';
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'类型', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'analysis_runtime_year', @level2type=N'Column', @level2name=N'item_type';
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'1月用量或比值', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'analysis_runtime_year', @level2type=N'Column', @level2name=N'month01';
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'2月用量或比值', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'analysis_runtime_year', @level2type=N'Column', @level2name=N'month02';
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'3月用量或比值', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'analysis_runtime_year', @level2type=N'Column', @level2name=N'month03';
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'4月用量或比值', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'analysis_runtime_year', @level2type=N'Column', @level2name=N'month04';
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'5月用量或比值', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'analysis_runtime_year', @level2type=N'Column', @level2name=N'month05';
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'6月用量或比值', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'analysis_runtime_year', @level2type=N'Column', @level2name=N'month06';
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'7月用量或比值', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'analysis_runtime_year', @level2type=N'Column', @level2name=N'month07';
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'8月用量或比值', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'analysis_runtime_year', @level2type=N'Column', @level2name=N'month08';
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'9月用量或比值', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'analysis_runtime_year', @level2type=N'Column', @level2name=N'month09';
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'10月用量或比值', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'analysis_runtime_year', @level2type=N'Column', @level2name=N'month10';
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'11月用量或比值', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'analysis_runtime_year', @level2type=N'Column', @level2name=N'month11';
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'12月用量或比值', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'analysis_runtime_year', @level2type=N'Column', @level2name=N'month12';
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'合计用量', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'analysis_runtime_year', @level2type=N'Column', @level2name=N'total_value';
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'楼栋编号', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'analysis_runtime_year', @level2type=N'Column', @level2name=N'building_id';
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'楼栋名称', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'analysis_runtime_year', @level2type=N'Column', @level2name=N'building_name';
-- 2024-06-24 添加楼栋人数
alter table history_data_pre add people_num numeric(24,2) not null default 0;
exec sp_addextendedproperty N'MS_Description', N'每栋楼人数', N'schema', N'dbo',N'table', N'history_data_pre', N'column', N'people_num';
-- 2024-06-26 添加知识库
CREATE TABLE knowledge_data
(
id bigint IDENTITY(1,1) NOT NULL,
title varchar(100) COLLATE Chinese_PRC_CI_AS NULL,
description varchar(200) COLLATE Chinese_PRC_CI_AS NULL,
content varchar(2000) COLLATE Chinese_PRC_CI_AS NULL,
create_time datetime NULL,
status int NULL,
remark varchar(200) COLLATE Chinese_PRC_CI_AS NULL,
CONSTRAINT pk_knowledge_data PRIMARY KEY (id)
);
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'知识库数据', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'knowledge_data';
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'id', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'knowledge_data', @level2type=N'Column', @level2name=N'id';
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'标题', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'knowledge_data', @level2type=N'Column', @level2name=N'title';
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'描述', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'knowledge_data', @level2type=N'Column', @level2name=N'description';
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'内容', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'knowledge_data', @level2type=N'Column', @level2name=N'content';
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'创建时间', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'knowledge_data', @level2type=N'Column', @level2name=N'create_time';
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'状态', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'knowledge_data', @level2type=N'Column', @level2name=N'status';
EXEC sp_addextendedproperty @name=N'MS_Description', @value=N'备注', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'knowledge_data', @level2type=N'Column', @level2name=N'remark';
create index knowledge_data_create_time on history_data_pre (create_time);
-- 2024-07-01 水位变换添加
ALTER TABLE chws_gsh.dbo.waterLevel ADD level14 varchar(50) NULL;
EXEC chws_gsh.sys.sp_addextendedproperty 'MS_Description', N'14点水位', 'schema', N'dbo', 'table', N'waterLevel', 'column', N'level14';
ALTER TABLE chws_gsh.dbo.building ADD low_tank_height numeric(24,2) NULL;
EXEC chws_gsh.sys.sp_addextendedproperty 'MS_Description', N'低区域水箱高度', 'schema', N'dbo', 'table', N'building', 'column', N'low_tank_height';

135
algorithm/pom.xml

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.mh</groupId>
<artifactId>chws</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mh</groupId>
<artifactId>algorithm</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<encoding>UTF-8</encoding>
<java.version>1.8</java.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/net.sourceforge.javacsv/javacsv -->
<dependency>
<groupId>net.sourceforge.javacsv</groupId>
<artifactId>javacsv</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>gov.nist.math</groupId>
<artifactId>jama</artifactId>
<version>1.0.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>RELEASE</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.9.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugins>
<!-- java版本 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<!-- 这是javadoc打包插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
<!-- 该处屏蔽jdk1.8后javadoc的严格校验 -->
<configuration>
<additionalparam>-Xdoclint:none</additionalparam>
</configuration>
</execution>
</executions>
</plugin>
<!-- 打包源码插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<!--签名插件-->
<!-- <plugin>-->
<!-- <groupId>org.apache.maven.plugins</groupId>-->
<!-- <artifactId>maven-gpg-plugin</artifactId>-->
<!-- <version>1.4</version>-->
<!-- <executions>-->
<!-- <execution>-->
<!-- <id>sign-artifacts</id>-->
<!-- <phase>verify</phase>-->
<!-- <goals>-->
<!-- <goal>sign</goal>-->
<!-- </goals>-->
<!-- </execution>-->
<!-- </executions>-->
<!-- </plugin>-->
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<classesDirectory>target/classes</classesDirectory>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

8
algorithm/src/main/java/com/mh/algorithm/bpnn/ActivationFunction.java

@ -0,0 +1,8 @@
package com.mh.algorithm.bpnn;
public interface ActivationFunction {
//计算值
double computeValue(double val);
//计算导数
double computeDerivative(double val);
}

111
algorithm/src/main/java/com/mh/algorithm/bpnn/BPModel.java

@ -0,0 +1,111 @@
package com.mh.algorithm.bpnn;
import com.mh.algorithm.matrix.Matrix;
import java.io.Serializable;
public class BPModel implements Serializable {
//BP神经网络权值与阈值
private Matrix weightIJ;
private Matrix b1;
private Matrix weightJP;
private Matrix b2;
/*用于反归一化*/
private Matrix inputMax;
private Matrix inputMin;
private Matrix outputMax;
private Matrix outputMin;
/*BP神经网络训练参数*/
private BPParameter bpParameter;
/*BP神经网络训练情况*/
private double error;
private int times;
public Matrix getWeightIJ() {
return weightIJ;
}
public void setWeightIJ(Matrix weightIJ) {
this.weightIJ = weightIJ;
}
public Matrix getB1() {
return b1;
}
public void setB1(Matrix b1) {
this.b1 = b1;
}
public Matrix getWeightJP() {
return weightJP;
}
public void setWeightJP(Matrix weightJP) {
this.weightJP = weightJP;
}
public Matrix getB2() {
return b2;
}
public void setB2(Matrix b2) {
this.b2 = b2;
}
public Matrix getInputMax() {
return inputMax;
}
public void setInputMax(Matrix inputMax) {
this.inputMax = inputMax;
}
public Matrix getInputMin() {
return inputMin;
}
public void setInputMin(Matrix inputMin) {
this.inputMin = inputMin;
}
public Matrix getOutputMax() {
return outputMax;
}
public void setOutputMax(Matrix outputMax) {
this.outputMax = outputMax;
}
public Matrix getOutputMin() {
return outputMin;
}
public void setOutputMin(Matrix outputMin) {
this.outputMin = outputMin;
}
public BPParameter getBpParameter() {
return bpParameter;
}
public void setBpParameter(BPParameter bpParameter) {
this.bpParameter = bpParameter;
}
public double getError() {
return error;
}
public void setError(double error) {
this.error = error;
}
public int getTimes() {
return times;
}
public void setTimes(int times) {
this.times = times;
}
}

262
algorithm/src/main/java/com/mh/algorithm/bpnn/BPNeuralNetworkFactory.java

@ -0,0 +1,262 @@
package com.mh.algorithm.bpnn;
import com.mh.algorithm.matrix.Matrix;
import com.mh.algorithm.utils.MatrixUtil;
import java.util.*;
public class BPNeuralNetworkFactory {
/**
* 训练BP神经网络模型
* @param bpParameter
* @param inputAndOutput
* @return
*/
public BPModel trainBP(BPParameter bpParameter, Matrix inputAndOutput) throws Exception {
ActivationFunction activationFunction = bpParameter.getActivationFunction();
int inputCount = bpParameter.getInputLayerNeuronCount();
int hiddenCount = bpParameter.getHiddenLayerNeuronCount();
int outputCount = bpParameter.getOutputLayerNeuronCount();
double normalizationMin = bpParameter.getNormalizationMin();
double normalizationMax = bpParameter.getNormalizationMax();
double step = bpParameter.getStep();
double momentumFactor = bpParameter.getMomentumFactor();
double precision = bpParameter.getPrecision();
int maxTimes = bpParameter.getMaxTimes();
if(inputAndOutput.getMatrixColCount() != inputCount + outputCount){
throw new Exception("神经元个数不符,请修改");
}
// 初始化权值
Matrix weightIJ = initWeight(inputCount, hiddenCount);
Matrix weightJP = initWeight(hiddenCount, outputCount);
// 初始化阈值
Matrix b1 = initThreshold(hiddenCount);
Matrix b2 = initThreshold(outputCount);
// 动量项
Matrix deltaWeightIJ0 = new Matrix(inputCount, hiddenCount);
Matrix deltaWeightJP0 = new Matrix(hiddenCount, outputCount);
Matrix deltaB10 = new Matrix(1, hiddenCount);
Matrix deltaB20 = new Matrix(1, outputCount);
// 截取输入矩阵和输出矩阵
Matrix input = inputAndOutput.subMatrix(0,inputAndOutput.getMatrixRowCount(),0,inputCount);
Matrix output = inputAndOutput.subMatrix(0,inputAndOutput.getMatrixRowCount(),inputCount,outputCount);
// 归一化
Map<String,Object> inputAfterNormalize = MatrixUtil.normalize(input, normalizationMin, normalizationMax);
input = (Matrix) inputAfterNormalize.get("res");
Map<String,Object> outputAfterNormalize = MatrixUtil.normalize(output, normalizationMin, normalizationMax);
output = (Matrix) outputAfterNormalize.get("res");
int times = 1;
double E = 0;//误差
while (times < maxTimes) {
/*-----------------正向传播---------------------*/
// 隐含层输入
Matrix jIn = input.multiple(weightIJ);
// 扩充阈值
Matrix b1Copy = b1.extend(2,jIn.getMatrixRowCount());
// 加上阈值
jIn = jIn.plus(b1Copy);
// 隐含层输出
Matrix jOut = computeValue(jIn,activationFunction);
// 输出层输入
Matrix pIn = jOut.multiple(weightJP);
// 扩充阈值
Matrix b2Copy = b2.extend(2, pIn.getMatrixRowCount());
// 加上阈值
pIn = pIn.plus(b2Copy);
// 输出层输出
Matrix pOut = computeValue(pIn,activationFunction);
// 计算误差
Matrix e = output.subtract(pOut);
E = computeE(e);//误差
// 判断是否符合精度
if (Math.abs(E) <= precision) {
System.out.println("满足精度");
break;
}
/*-----------------反向传播---------------------*/
// J与P之间权值修正量
Matrix deltaWeightJP = e.multiple(step);
deltaWeightJP = deltaWeightJP.pointMultiple(computeDerivative(pIn,activationFunction));
deltaWeightJP = deltaWeightJP.transpose().multiple(jOut);
deltaWeightJP = deltaWeightJP.transpose();
// P层神经元阈值修正量
Matrix deltaThresholdP = e.multiple(step);
deltaThresholdP = deltaThresholdP.transpose().multiple(computeDerivative(pIn, activationFunction));
// I与J之间的权值修正量
Matrix deltaO = e.pointMultiple(computeDerivative(pIn,activationFunction));
Matrix tmp = weightJP.multiple(deltaO.transpose()).transpose();
Matrix deltaWeightIJ = tmp.pointMultiple(computeDerivative(jIn, activationFunction));
deltaWeightIJ = input.transpose().multiple(deltaWeightIJ);
deltaWeightIJ = deltaWeightIJ.multiple(step);
// J层神经元阈值修正量
Matrix deltaThresholdJ = tmp.transpose().multiple(computeDerivative(jIn, activationFunction));
deltaThresholdJ = deltaThresholdJ.multiple(-step);
if (times == 1) {
// 更新权值与阈值
weightIJ = weightIJ.plus(deltaWeightIJ);
weightJP = weightJP.plus(deltaWeightJP);
b1 = b1.plus(deltaThresholdJ);
b2 = b2.plus(deltaThresholdP);
}else{
// 加动量项
weightIJ = weightIJ.plus(deltaWeightIJ).plus(deltaWeightIJ0.multiple(momentumFactor));
weightJP = weightJP.plus(deltaWeightJP).plus(deltaWeightJP0.multiple(momentumFactor));
b1 = b1.plus(deltaThresholdJ).plus(deltaB10.multiple(momentumFactor));
b2 = b2.plus(deltaThresholdP).plus(deltaB20.multiple(momentumFactor));
}
deltaWeightIJ0 = deltaWeightIJ;
deltaWeightJP0 = deltaWeightJP;
deltaB10 = deltaThresholdJ;
deltaB20 = deltaThresholdP;
times++;
}
// BP神经网络的输出
BPModel result = new BPModel();
result.setInputMax((Matrix) inputAfterNormalize.get("max"));
result.setInputMin((Matrix) inputAfterNormalize.get("min"));
result.setOutputMax((Matrix) outputAfterNormalize.get("max"));
result.setOutputMin((Matrix) outputAfterNormalize.get("min"));
result.setWeightIJ(weightIJ);
result.setWeightJP(weightJP);
result.setB1(b1);
result.setB2(b2);
result.setError(E);
result.setTimes(times);
result.setBpParameter(bpParameter);
System.out.println("循环次数:" + times + ",误差:" + E);
return result;
}
/**
* 计算BP神经网络的值
* @param bpModel
* @param input
* @return
*/
public Matrix computeBP(BPModel bpModel,Matrix input) throws Exception {
if (input.getMatrixColCount() != bpModel.getBpParameter().getInputLayerNeuronCount()) {
throw new Exception("输入矩阵纬度有误");
}
ActivationFunction activationFunction = bpModel.getBpParameter().getActivationFunction();
Matrix weightIJ = bpModel.getWeightIJ();
Matrix weightJP = bpModel.getWeightJP();
Matrix b1 = bpModel.getB1();
Matrix b2 = bpModel.getB2();
double[][] normalizedInput = new double[input.getMatrixRowCount()][input.getMatrixColCount()];
for (int i = 0; i < input.getMatrixRowCount(); i++) {
for (int j = 0; j < input.getMatrixColCount(); j++) {
if ((input.getValOfIdx(i,j) - bpModel.getInputMin().getValOfIdx(0,j)) == 0
|| (bpModel.getInputMax().getValOfIdx(0,j) - bpModel.getInputMin().getValOfIdx(0,j)) == 0) {
normalizedInput[i][j] = bpModel.getBpParameter().getNormalizationMin();
continue;
}
normalizedInput[i][j] = bpModel.getBpParameter().getNormalizationMin()
+ (input.getValOfIdx(i,j) - bpModel.getInputMin().getValOfIdx(0,j))
/ (bpModel.getInputMax().getValOfIdx(0,j) - bpModel.getInputMin().getValOfIdx(0,j))
* (bpModel.getBpParameter().getNormalizationMax() - bpModel.getBpParameter().getNormalizationMin());
}
}
Matrix normalizedInputMatrix = new Matrix(normalizedInput);
Matrix jIn = normalizedInputMatrix.multiple(weightIJ);
// 扩充阈值
Matrix b1Copy = b1.extend(2,jIn.getMatrixRowCount());
// 加上阈值
jIn = jIn.plus(b1Copy);
// 隐含层输出
Matrix jOut = computeValue(jIn,activationFunction);
// 输出层输入
Matrix pIn = jOut.multiple(weightJP);
// 扩充阈值
Matrix b2Copy = b2.extend(2,pIn.getMatrixRowCount());
// 加上阈值
pIn = pIn.plus(b2Copy);
// 输出层输出
Matrix pOut = computeValue(pIn,activationFunction);
// 反归一化
return MatrixUtil.inverseNormalize(pOut, bpModel.getBpParameter().getNormalizationMax(), bpModel.getBpParameter().getNormalizationMin(), bpModel.getOutputMax(), bpModel.getOutputMin());
}
// 初始化权值
private Matrix initWeight(int x,int y){
Random random=new Random();
double[][] weight = new double[x][y];
for (int i = 0; i < x; i++) {
for (int j = 0; j < y; j++) {
weight[i][j] = 2*random.nextDouble()-1;
}
}
return new Matrix(weight);
}
// 初始化阈值
private Matrix initThreshold(int x){
Random random = new Random();
double[][] result = new double[1][x];
for (int i = 0; i < x; i++) {
result[0][i] = 2*random.nextDouble()-1;
}
return new Matrix(result);
}
/**
* 计算激活函数的值
* @param a
* @return
*/
private Matrix computeValue(Matrix a, ActivationFunction activationFunction) throws Exception {
if (a.getMatrix() == null) {
throw new Exception("参数值为空");
}
double[][] result = new double[a.getMatrixRowCount()][a.getMatrixColCount()];
for (int i = 0; i < a.getMatrixRowCount(); i++) {
for (int j = 0; j < a.getMatrixColCount(); j++) {
result[i][j] = activationFunction.computeValue(a.getValOfIdx(i,j));
}
}
return new Matrix(result);
}
/**
* 激活函数导数的值
* @param a
* @return
*/
private Matrix computeDerivative(Matrix a , ActivationFunction activationFunction) throws Exception {
if (a.getMatrix() == null) {
throw new Exception("参数值为空");
}
double[][] result = new double[a.getMatrixRowCount()][a.getMatrixColCount()];
for (int i = 0; i < a.getMatrixRowCount(); i++) {
for (int j = 0; j < a.getMatrixColCount(); j++) {
result[i][j] = activationFunction.computeDerivative(a.getValOfIdx(i,j));
}
}
return new Matrix(result);
}
/**
* 计算误差
* @param e
* @return
*/
private double computeE(Matrix e){
e = e.square();
return 0.5*e.sumAll();
}
}

106
algorithm/src/main/java/com/mh/algorithm/bpnn/BPParameter.java

@ -0,0 +1,106 @@
package com.mh.algorithm.bpnn;
import java.io.Serializable;
public class BPParameter implements Serializable {
//输入层神经元个数
private int inputLayerNeuronCount = 3;
//隐含层神经元个数
private int hiddenLayerNeuronCount = 3;
//输出层神经元个数
private int outputLayerNeuronCount = 1;
//归一化区间
private double normalizationMin = 0.2;
private double normalizationMax = 0.8;
//学习步长
private double step = 0.05;
//动量因子
private double momentumFactor = 0.2;
//激活函数
private ActivationFunction activationFunction = new Sigmoid();
//精度
private double precision = 0.000001;
//最大循环次数
private int maxTimes = 1000000;
public double getMomentumFactor() {
return momentumFactor;
}
public void setMomentumFactor(double momentumFactor) {
this.momentumFactor = momentumFactor;
}
public double getStep() {
return step;
}
public void setStep(double step) {
this.step = step;
}
public double getNormalizationMin() {
return normalizationMin;
}
public void setNormalizationMin(double normalizationMin) {
this.normalizationMin = normalizationMin;
}
public double getNormalizationMax() {
return normalizationMax;
}
public void setNormalizationMax(double normalizationMax) {
this.normalizationMax = normalizationMax;
}
public int getInputLayerNeuronCount() {
return inputLayerNeuronCount;
}
public void setInputLayerNeuronCount(int inputLayerNeuronCount) {
this.inputLayerNeuronCount = inputLayerNeuronCount;
}
public int getHiddenLayerNeuronCount() {
return hiddenLayerNeuronCount;
}
public void setHiddenLayerNeuronCount(int hiddenLayerNeuronCount) {
this.hiddenLayerNeuronCount = hiddenLayerNeuronCount;
}
public int getOutputLayerNeuronCount() {
return outputLayerNeuronCount;
}
public void setOutputLayerNeuronCount(int outputLayerNeuronCount) {
this.outputLayerNeuronCount = outputLayerNeuronCount;
}
public ActivationFunction getActivationFunction() {
return activationFunction;
}
public void setActivationFunction(ActivationFunction activationFunction) {
this.activationFunction = activationFunction;
}
public double getPrecision() {
return precision;
}
public void setPrecision(double precision) {
this.precision = precision;
}
public int getMaxTimes() {
return maxTimes;
}
public void setMaxTimes(int maxTimes) {
this.maxTimes = maxTimes;
}
}

15
algorithm/src/main/java/com/mh/algorithm/bpnn/Sigmoid.java

@ -0,0 +1,15 @@
package com.mh.algorithm.bpnn;
import java.io.Serializable;
public class Sigmoid implements ActivationFunction, Serializable {
@Override
public double computeValue(double val) {
return 1 / (1 + Math.exp(-val));
}
@Override
public double computeDerivative(double val) {
return computeValue(val) * (1 - computeValue(val));
}
}

24
algorithm/src/main/java/com/mh/algorithm/constants/OrderEnum.java

@ -0,0 +1,24 @@
package com.mh.algorithm.constants;
/**
* 排序枚举类
*/
public enum OrderEnum {
ASC(1,"升序"),
DESC(2,"降序");
OrderEnum(int flag, String name) {
this.flag = flag;
this.name = name;
}
private int flag;
private String name;
}

88
algorithm/src/main/java/com/mh/algorithm/knn/KNN.java

@ -0,0 +1,88 @@
package com.mh.algorithm.knn;
import com.mh.algorithm.constants.OrderEnum;
import com.mh.algorithm.matrix.Matrix;
import com.mh.algorithm.utils.MatrixUtil;
import java.util.*;
/**
* @program: top-algorithm-set
* @description: KNN k-临近算法进行分类
* @author: Mr.Zhao
* @create: 2020-10-13 22:03
**/
public class KNN {
public static Matrix classify(Matrix input, Matrix dataSet, Matrix labels, int k) throws Exception {
if (dataSet.getMatrixRowCount() != labels.getMatrixRowCount()) {
throw new IllegalArgumentException("矩阵训练集与标签维度不一致");
}
if (input.getMatrixColCount() != dataSet.getMatrixColCount()) {
throw new IllegalArgumentException("待分类矩阵列数与训练集列数不一致");
}
if (dataSet.getMatrixRowCount() < k) {
throw new IllegalArgumentException("训练集样本数小于k");
}
// 归一化
int trainCount = dataSet.getMatrixRowCount();
int testCount = input.getMatrixRowCount();
Matrix trainAndTest = dataSet.splice(2, input);
Map<String, Object> normalize = MatrixUtil.normalize(trainAndTest, 0, 1);
trainAndTest = (Matrix) normalize.get("res");
dataSet = trainAndTest.subMatrix(0, trainCount, 0, trainAndTest.getMatrixColCount());
input = trainAndTest.subMatrix(0, testCount, 0, trainAndTest.getMatrixColCount());
// 获取标签信息
List<Double> labelList = new ArrayList<>();
for (int i = 0; i < labels.getMatrixRowCount(); i++) {
if (!labelList.contains(labels.getValOfIdx(i, 0))) {
labelList.add(labels.getValOfIdx(i, 0));
}
}
Matrix result = new Matrix(new double[input.getMatrixRowCount()][1]);
for (int i = 0; i < input.getMatrixRowCount(); i++) {
// 计算向量间的欧式距离
// 将labels矩阵扩展
Matrix labelMatrixCopied = input.getRowOfIdx(i).extend(2, dataSet.getMatrixRowCount());
// 前面是计算欧氏距离,splice(1,labels)是将距离矩阵与labels矩阵合并
Matrix distanceMatrix = dataSet.subtract(labelMatrixCopied).square().sumRow().pow(0.5).splice(1, labels);
// 将计算出的距离矩阵按照距离升序排序
distanceMatrix.sort(0, OrderEnum.ASC);
// 遍历最近的k个变量
Map<Double, Integer> map = new HashMap<>();
for (int j = 0; j < k; j++) {
// 遍历标签种类数
for (Double label : labelList) {
if (distanceMatrix.getValOfIdx(j, 1) == label) {
map.put(label, map.getOrDefault(label, 0) + 1);
}
}
}
result.setValue(i, 0, getKeyOfMaxValue(map));
}
return result;
}
/**
* 取map中值最大的key
*
* @param map
* @return
*/
private static Double getKeyOfMaxValue(Map<Double, Integer> map) {
if (map == null)
return null;
Double keyOfMaxValue = 0.0;
Integer maxValue = 0;
for (Double key : map.keySet()) {
if (map.get(key) > maxValue) {
keyOfMaxValue = key;
maxValue = map.get(key);
}
}
return keyOfMaxValue;
}
}

646
algorithm/src/main/java/com/mh/algorithm/matrix/Matrix.java

@ -0,0 +1,646 @@
package com.mh.algorithm.matrix;
import com.mh.algorithm.constants.OrderEnum;
import java.io.Serializable;
public class Matrix implements Serializable {
private double[][] matrix;
//矩阵列数
private int matrixColCount;
//矩阵行数
private int matrixRowCount;
/**
* 构造一个空矩阵
*/
public Matrix() {
this.matrix = null;
this.matrixColCount = 0;
this.matrixRowCount = 0;
}
/**
* 构造一个matrix矩阵
* @param matrix
*/
public Matrix(double[][] matrix) {
this.matrix = matrix;
this.matrixRowCount = matrix.length;
this.matrixColCount = matrix[0].length;
}
/**
* 构造一个rowCount行colCount列值为0的矩阵
* @param rowCount
* @param colCount
*/
public Matrix(int rowCount,int colCount) {
double[][] matrix = new double[rowCount][colCount];
for (int i = 0; i < rowCount; i++) {
for (int j = 0; j < colCount; j++) {
matrix[i][j] = 0;
}
}
this.matrix = matrix;
this.matrixRowCount = rowCount;
this.matrixColCount = colCount;
}
/**
* 构造一个rowCount行colCount列值为val的矩阵
* @param val
* @param rowCount
* @param colCount
*/
public Matrix(double val,int rowCount,int colCount) {
double[][] matrix = new double[rowCount][colCount];
for (int i = 0; i < rowCount; i++) {
for (int j = 0; j < colCount; j++) {
matrix[i][j] = val;
}
}
this.matrix = matrix;
this.matrixRowCount = rowCount;
this.matrixColCount = colCount;
}
public double[][] getMatrix() {
return matrix;
}
public void setMatrix(double[][] matrix) {
this.matrix = matrix;
this.matrixRowCount = matrix.length;
this.matrixColCount = matrix[0].length;
}
public int getMatrixColCount() {
return matrixColCount;
}
public int getMatrixRowCount() {
return matrixRowCount;
}
/**
* 获取矩阵指定位置的值
*
* @param x
* @param y
* @return
*/
public double getValOfIdx(int x, int y) throws IllegalArgumentException {
if (matrix == null || matrixRowCount == 0 || matrixColCount == 0) {
throw new IllegalArgumentException("矩阵为空");
}
if (x > matrixRowCount - 1) {
throw new IllegalArgumentException("索引x越界");
}
if (y > matrixColCount - 1) {
throw new IllegalArgumentException("索引y越界");
}
return matrix[x][y];
}
/**
* 获取矩阵指定行
*
* @param x
* @return
*/
public Matrix getRowOfIdx(int x) throws IllegalArgumentException {
if (matrix == null || matrixRowCount == 0 || matrixColCount == 0) {
throw new IllegalArgumentException("矩阵为空");
}
if (x > matrixRowCount - 1) {
throw new IllegalArgumentException("索引x越界");
}
double[][] result = new double[1][matrixColCount];
result[0] = matrix[x];
return new Matrix(result);
}
/**
* 获取矩阵指定列
*
* @param y
* @return
*/
public Matrix getColOfIdx(int y) throws IllegalArgumentException {
if (matrix == null || matrixRowCount == 0 || matrixColCount == 0) {
throw new IllegalArgumentException("矩阵为空");
}
if (y > matrixColCount - 1) {
throw new IllegalArgumentException("索引y越界");
}
double[][] result = new double[matrixRowCount][1];
for (int i = 0; i < matrixRowCount; i++) {
result[i][0] = matrix[i][y];
}
return new Matrix(result);
}
/**
* 设置矩阵中x,y位置元素的值
* @param x
* @param y
* @param val
*/
public void setValue(int x, int y, double val) {
if (x > this.matrixRowCount - 1) {
throw new IllegalArgumentException("行索引越界");
}
if (y > this.matrixColCount - 1) {
throw new IllegalArgumentException("列索引越界");
}
this.matrix[x][y] = val;
}
/**
* 矩阵乘矩阵
*
* @param a
* @return
* @throws IllegalArgumentException
*/
public Matrix multiple(Matrix a) throws IllegalArgumentException {
if (matrix == null || matrixRowCount == 0 || matrixColCount == 0) {
throw new IllegalArgumentException("矩阵为空");
}
if (a.getMatrix() == null || a.getMatrixRowCount() == 0 || a.getMatrixColCount() == 0) {
throw new IllegalArgumentException("参数矩阵为空");
}
if (matrixColCount != a.getMatrixRowCount()) {
throw new IllegalArgumentException("矩阵纬度不同,不可计算");
}
double[][] result = new double[matrixRowCount][a.getMatrixColCount()];
for (int i = 0; i < matrixRowCount; i++) {
for (int j = 0; j < a.getMatrixColCount(); j++) {
for (int k = 0; k < matrixColCount; k++) {
result[i][j] = result[i][j] + matrix[i][k] * a.getMatrix()[k][j];
}
}
}
return new Matrix(result);
}
/**
* 矩阵乘一个数字
*
* @param a
* @return
*/
public Matrix multiple(double a) throws IllegalArgumentException {
if (matrix == null || matrixRowCount == 0 || matrixColCount == 0) {
throw new IllegalArgumentException("矩阵为空");
}
double[][] result = new double[matrixRowCount][matrixColCount];
for (int i = 0; i < matrixRowCount; i++) {
for (int j = 0; j < matrixColCount; j++) {
result[i][j] = matrix[i][j] * a;
}
}
return new Matrix(result);
}
/**
* 矩阵点乘
*
* @param a
* @return
*/
public Matrix pointMultiple(Matrix a) throws IllegalArgumentException {
if (matrix == null || matrixRowCount == 0 || matrixColCount == 0) {
throw new IllegalArgumentException("矩阵为空");
}
if (a.getMatrix() == null || a.getMatrixRowCount() == 0 || a.getMatrixColCount() == 0) {
throw new IllegalArgumentException("参数矩阵为空");
}
if (matrixRowCount != a.getMatrixRowCount() && matrixColCount != a.getMatrixColCount()) {
throw new IllegalArgumentException("矩阵纬度不同,不可计算");
}
double[][] result = new double[matrixRowCount][matrixColCount];
for (int i = 0; i < matrixRowCount; i++) {
for (int j = 0; j < matrixColCount; j++) {
result[i][j] = matrix[i][j] * a.getMatrix()[i][j];
}
}
return new Matrix(result);
}
/**
* 矩阵除一个数字
* @param a
* @return
* @throws IllegalArgumentException
*/
public Matrix divide(double a) throws IllegalArgumentException {
if (matrix == null || matrixRowCount == 0 || matrixColCount == 0) {
throw new IllegalArgumentException("矩阵为空");
}
double[][] result = new double[matrixRowCount][matrixColCount];
for (int i = 0; i < matrixRowCount; i++) {
for (int j = 0; j < matrixColCount; j++) {
result[i][j] = matrix[i][j] / a;
}
}
return new Matrix(result);
}
/**
* 矩阵加法
*
* @param a
* @return
*/
public Matrix plus(Matrix a) throws IllegalArgumentException {
if (matrix == null || matrixRowCount == 0 || matrixColCount == 0) {
throw new IllegalArgumentException("矩阵为空");
}
if (a.getMatrix() == null || a.getMatrixRowCount() == 0 || a.getMatrixColCount() == 0) {
throw new IllegalArgumentException("参数矩阵为空");
}
if (matrixRowCount != a.getMatrixRowCount() && matrixColCount != a.getMatrixColCount()) {
throw new IllegalArgumentException("矩阵纬度不同,不可计算");
}
double[][] result = new double[matrixRowCount][matrixColCount];
for (int i = 0; i < matrixRowCount; i++) {
for (int j = 0; j < matrixColCount; j++) {
result[i][j] = matrix[i][j] + a.getMatrix()[i][j];
}
}
return new Matrix(result);
}
/**
* 矩阵加一个数字
* @param a
* @return
* @throws IllegalArgumentException
*/
public Matrix plus(double a) throws IllegalArgumentException {
if (matrix == null || matrixRowCount == 0 || matrixColCount == 0) {
throw new IllegalArgumentException("矩阵为空");
}
double[][] result = new double[matrixRowCount][matrixColCount];
for (int i = 0; i < matrixRowCount; i++) {
for (int j = 0; j < matrixColCount; j++) {
result[i][j] = matrix[i][j] + a;
}
}
return new Matrix(result);
}
/**
* 矩阵减法
*
* @param a
* @return
*/
public Matrix subtract(Matrix a) throws IllegalArgumentException {
if (matrix == null || matrixRowCount == 0 || matrixColCount == 0) {
throw new IllegalArgumentException("矩阵为空");
}
if (a.getMatrix() == null || a.getMatrixRowCount() == 0 || a.getMatrixColCount() == 0) {
throw new IllegalArgumentException("参数矩阵为空");
}
if (matrixRowCount != a.getMatrixRowCount() && matrixColCount != a.getMatrixColCount()) {
throw new IllegalArgumentException("矩阵纬度不同,不可计算");
}
double[][] result = new double[matrixRowCount][matrixColCount];
for (int i = 0; i < matrixRowCount; i++) {
for (int j = 0; j < matrixColCount; j++) {
result[i][j] = matrix[i][j] - a.getMatrix()[i][j];
}
}
return new Matrix(result);
}
/**
* 矩阵减一个数字
* @param a
* @return
* @throws IllegalArgumentException
*/
public Matrix subtract(double a) throws IllegalArgumentException {
if (matrix == null || matrixRowCount == 0 || matrixColCount == 0) {
throw new IllegalArgumentException("矩阵为空");
}
double[][] result = new double[matrixRowCount][matrixColCount];
for (int i = 0; i < matrixRowCount; i++) {
for (int j = 0; j < matrixColCount; j++) {
result[i][j] = matrix[i][j] - a;
}
}
return new Matrix(result);
}
/**
* 矩阵行求和
*
* @return
*/
public Matrix sumRow() throws IllegalArgumentException {
if (matrix == null || matrixRowCount == 0 || matrixColCount == 0) {
throw new IllegalArgumentException("矩阵为空");
}
double[][] result = new double[matrixRowCount][1];
for (int i = 0; i < matrixRowCount; i++) {
for (int j = 0; j < matrixColCount; j++) {
result[i][0] += matrix[i][j];
}
}
return new Matrix(result);
}
/**
* 矩阵列求和
*
* @return
*/
public Matrix sumCol() throws IllegalArgumentException {
if (matrix == null || matrixRowCount == 0 || matrixColCount == 0) {
throw new IllegalArgumentException("矩阵为空");
}
double[][] result = new double[1][matrixColCount];
for (int i = 0; i < matrixRowCount; i++) {
for (int j = 0; j < matrixColCount; j++) {
result[0][j] += matrix[i][j];
}
}
return new Matrix(result);
}
/**
* 矩阵所有元素求和
*
* @return
*/
public double sumAll() throws IllegalArgumentException {
if (matrix == null || matrixRowCount == 0 || matrixColCount == 0) {
throw new IllegalArgumentException("矩阵为空");
}
double result = 0;
for (double[] doubles : matrix) {
for (int j = 0; j < matrixColCount; j++) {
result += doubles[j];
}
}
return result;
}
/**
* 矩阵所有元素求平方
*
* @return
*/
public Matrix square() throws IllegalArgumentException {
if (matrix == null || matrixRowCount == 0 || matrixColCount == 0) {
throw new IllegalArgumentException("矩阵为空");
}
double[][] result = new double[matrixRowCount][matrixColCount];
for (int i = 0; i < matrixRowCount; i++) {
for (int j = 0; j < matrixColCount; j++) {
result[i][j] = matrix[i][j] * matrix[i][j];
}
}
return new Matrix(result);
}
/**
* 矩阵所有元素求N次方
*
* @return
*/
public Matrix pow(double n) throws IllegalArgumentException {
if (matrix == null || matrixRowCount == 0 || matrixColCount == 0) {
throw new IllegalArgumentException("矩阵为空");
}
double[][] result = new double[matrixRowCount][matrixColCount];
for (int i = 0; i < matrixRowCount; i++) {
for (int j = 0; j < matrixColCount; j++) {
result[i][j] = Math.pow(matrix[i][j],n);
}
}
return new Matrix(result);
}
/**
* 矩阵转置
*
* @return
*/
public Matrix transpose() throws IllegalArgumentException {
if (matrix == null || matrixRowCount == 0 || matrixColCount == 0) {
throw new IllegalArgumentException("矩阵为空");
}
double[][] result = new double[matrixColCount][matrixRowCount];
for (int i = 0; i < matrixRowCount; i++) {
for (int j = 0; j < matrixColCount; j++) {
result[j][i] = matrix[i][j];
}
}
return new Matrix(result);
}
/**
* 截取矩阵
* @param startRowIndex 开始行索引
* @param rowCount 截取行数
* @param startColIndex 开始列索引
* @param colCount 截取列数
* @return
* @throws IllegalArgumentException
*/
public Matrix subMatrix(int startRowIndex,int rowCount,int startColIndex,int colCount) throws IllegalArgumentException {
if (startRowIndex + rowCount > matrixRowCount) {
throw new IllegalArgumentException("行索引越界");
}
if (startColIndex + colCount> matrixColCount) {
throw new IllegalArgumentException("列索引越界");
}
double[][] result = new double[rowCount][colCount];
for (int i = startRowIndex; i < startRowIndex + rowCount; i++) {
if (startColIndex + colCount - startColIndex >= 0)
System.arraycopy(matrix[i], startColIndex, result[i - startRowIndex], 0, colCount);
}
return new Matrix(result);
}
/**
* 矩阵合并
* @param direction 合并方向1为横向2为竖向
* @param a
* @return
* @throws IllegalArgumentException
*/
public Matrix splice(int direction, Matrix a) throws IllegalArgumentException {
if (matrix == null || matrixRowCount == 0 || matrixColCount == 0) {
throw new IllegalArgumentException("矩阵为空");
}
if (a.getMatrix() == null || a.getMatrixRowCount() == 0 || a.getMatrixColCount() == 0) {
throw new IllegalArgumentException("参数矩阵为空");
}
if(direction == 1){
//横向拼接
if (matrixRowCount != a.getMatrixRowCount()) {
throw new IllegalArgumentException("矩阵行数不一致,无法拼接");
}
double[][] result = new double[matrixRowCount][matrixColCount + a.getMatrixColCount()];
for (int i = 0; i < matrixRowCount; i++) {
System.arraycopy(matrix[i],0,result[i],0,matrixColCount);
System.arraycopy(a.getMatrix()[i],0,result[i],matrixColCount,a.getMatrixColCount());
}
return new Matrix(result);
}else if(direction == 2){
//纵向拼接
if (matrixColCount != a.getMatrixColCount()) {
throw new IllegalArgumentException("矩阵列数不一致,无法拼接");
}
double[][] result = new double[matrixRowCount + a.getMatrixRowCount()][matrixColCount];
for (int i = 0; i < matrixRowCount; i++) {
result[i] = matrix[i];
}
for (int i = 0; i < a.getMatrixRowCount(); i++) {
result[matrixRowCount + i] = a.getMatrix()[i];
}
return new Matrix(result);
}else{
throw new IllegalArgumentException("方向参数有误");
}
}
/**
* 扩展矩阵
* @param direction 扩展方向1为横向2为竖向
* @param a
* @return
* @throws IllegalArgumentException
*/
public Matrix extend(int direction , int a) throws IllegalArgumentException {
if (matrix == null || matrixRowCount == 0 || matrixColCount == 0) {
throw new IllegalArgumentException("矩阵为空");
}
if(direction == 1){
//横向复制
double[][] result = new double[matrixRowCount][matrixColCount*a];
for (int i = 0; i < matrixRowCount; i++) {
for (int j = 0; j < a; j++) {
System.arraycopy(matrix[i],0,result[i],j*matrixColCount,matrixColCount);
}
}
return new Matrix(result);
}else if(direction == 2){
//纵向复制
double[][] result = new double[matrixRowCount*a][matrixColCount];
for (int i = 0; i < matrixRowCount*a; i++) {
result[i] = matrix[i%matrixRowCount];
}
return new Matrix(result);
}else{
throw new IllegalArgumentException("方向参数有误");
}
}
/**
* 获取每列的平均值
* @return
* @throws IllegalArgumentException
*/
public Matrix getColAvg() throws IllegalArgumentException {
Matrix tmp = this.sumCol();
return tmp.divide(matrixRowCount);
}
/**
* 矩阵行排序
* @param index 根据第几列的数进行行排序
* @param order 排序顺序升序或降序
* @return
* @throws IllegalArgumentException
*/
public void sort(int index, OrderEnum order) throws IllegalArgumentException{
if (matrix == null || matrixRowCount == 0 || matrixColCount == 0) {
throw new IllegalArgumentException("矩阵为空");
}
if(index >= matrixColCount){
throw new IllegalArgumentException("排序索引index越界");
}
sort(index,order,0,this.matrixRowCount - 1);
}
/**
* 判断是否是方阵
* 行列数相等并且不等于0
* @return
*/
public boolean isSquareMatrix(){
return matrixColCount == matrixRowCount && matrixColCount != 0;
}
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("\r\n");
for (int i = 0; i < matrixRowCount; i++) {
stringBuilder.append("# ");
for (int j = 0; j < matrixColCount; j++) {
stringBuilder.append(matrix[i][j]).append("\t ");
}
stringBuilder.append("#\r\n");
}
stringBuilder.append("\r\n");
return stringBuilder.toString();
}
private void sort(int index,OrderEnum order,int start,int end){
if(start >= end){
return;
}
int tmp = partition(index,order,start,end);
sort(index,order, start, tmp - 1);
sort(index,order, tmp + 1, end);
}
private int partition(int index,OrderEnum order,int start,int end){
int l = start + 1,r = end;
double v = matrix[start][index];
switch (order){
case ASC:
while(true){
while(matrix[r][index] >= v && r > start){
r--;
}
while(matrix[l][index] <= v && l < end){
l++;
}
if(l >= r){
break;
}
double[] tmp = matrix[r];
matrix[r] = matrix[l];
matrix[l] = tmp;
}
break;
case DESC:
while(true){
while(matrix[r][index] <= v && r > start){
r--;
}
while(matrix[l][index] >= v && l < end){
l++;
}
if(l >= r){
break;
}
double[] tmp = matrix[r];
matrix[r] = matrix[l];
matrix[l] = tmp;
}
break;
}
double[] tmp = matrix[r];
matrix[r] = matrix[start];
matrix[start] = tmp;
return r;
}
}

53
algorithm/src/main/java/com/mh/algorithm/utils/CsvInfo.java

@ -0,0 +1,53 @@
package com.mh.algorithm.utils;
import com.mh.algorithm.matrix.Matrix;
import java.util.ArrayList;
public class CsvInfo {
private String[] header;
private int csvRowCount;
private int csvColCount;
private ArrayList<String[]> csvFileList;
public String[] getHeader() {
return header;
}
public void setHeader(String[] header) {
this.header = header;
}
public int getCsvRowCount() {
return csvRowCount;
}
public int getCsvColCount() {
return csvColCount;
}
public ArrayList<String[]> getCsvFileList() {
return csvFileList;
}
public void setCsvFileList(ArrayList<String[]> csvFileList) {
this.csvFileList = csvFileList;
this.csvColCount = csvFileList.get(0) != null?csvFileList.get(0).length:0;
this.csvRowCount = csvFileList.size();
}
public Matrix toMatrix() throws Exception {
double[][] arr = new double[csvFileList.size()][csvFileList.get(0).length];
for (int i = 0; i < csvFileList.size(); i++) {
for (int j = 0; j < csvFileList.get(0).length; j++) {
try {
arr[i][j] = Double.parseDouble(csvFileList.get(i)[j]);
}catch (NumberFormatException e){
throw new Exception("Csv中含有非数字字符,无法转换成Matrix对象");
}
}
}
return new Matrix(arr);
}
}

66
algorithm/src/main/java/com/mh/algorithm/utils/CsvUtil.java

@ -0,0 +1,66 @@
package com.mh.algorithm.utils;
import com.csvreader.CsvReader;
import com.csvreader.CsvWriter;
import com.mh.algorithm.matrix.Matrix;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
public class CsvUtil {
/**
* 获取CSV中的信息
* @param hasHeader 是否含有表头
* @param path CSV文件的路径
* @return
* @throws IOException
*/
public static CsvInfo getCsvInfo(boolean hasHeader , String path) throws IOException {
//创建csv对象,存储csv中的信息
CsvInfo csvInfo = new CsvInfo();
//获取CsvReader流
CsvReader csvReader = new CsvReader(path, ',', StandardCharsets.UTF_8);
if(hasHeader){
csvReader.readHeaders();
}
//获取Csv中的所有记录
ArrayList<String[]> csvFileList = new ArrayList<String[]>();
while (csvReader.readRecord()) {
csvFileList.add(csvReader.getValues());
}
//赋值
csvInfo.setHeader(csvReader.getHeaders());
csvInfo.setCsvFileList(csvFileList);
//关闭流
csvReader.close();
return csvInfo;
}
/**
* 将矩阵写入到csv文件中
* @param header 表头
* @param data 以矩阵形式存放的数据
* @param path 写入的文件地址
* @throws Exception
*/
public static void createCsvFile(String[] header,Matrix data,String path) throws Exception {
if (header!=null && header.length != data.getMatrixColCount()) {
throw new Exception("表头列数与数据列数不符");
}
CsvWriter csvWriter = new CsvWriter(path, ',', StandardCharsets.UTF_8);
if (header != null) {
csvWriter.writeRecord(header);
}
for (int i = 0; i < data.getMatrixRowCount(); i++) {
String[] record = new String[data.getMatrixColCount()];
for (int j = 0; j < data.getMatrixColCount(); j++) {
record[j] = data.getValOfIdx(i, j)+"";
}
csvWriter.writeRecord(record);
}
csvWriter.close();
}
}

20
algorithm/src/main/java/com/mh/algorithm/utils/DoubleUtil.java

@ -0,0 +1,20 @@
package com.mh.algorithm.utils;
/**
* @program: top-algorithm-set
* @description: DoubleTool
* @author: Mr.Zhao
* @create: 2020-11-12 21:54
**/
public class DoubleUtil {
private static final Double MAX_ERROR = 0.0001;
public static boolean equals(Double a, Double b) {
return Math.abs(a - b)< MAX_ERROR;
}
public static boolean equals(Double a, Double b,Double maxError) {
return Math.abs(a - b)< maxError;
}
}

297
algorithm/src/main/java/com/mh/algorithm/utils/MatrixUtil.java

@ -0,0 +1,297 @@
package com.mh.algorithm.utils;
import Jama.EigenvalueDecomposition;
import com.mh.algorithm.matrix.Matrix;
import java.util.*;
public class MatrixUtil {
/**
* 创建一个单位矩阵
* @param matrixRowCount 单位矩阵的纬度
* @return
*/
public static Matrix eye(int matrixRowCount){
double[][] result = new double[matrixRowCount][matrixRowCount];
for (int i = 0; i < matrixRowCount; i++) {
for (int j = 0; j < matrixRowCount; j++) {
if(i == j){
result[i][j] = 1;
}else{
result[i][j] = 0;
}
}
}
return new Matrix(result);
}
/**
* 求矩阵的逆
* 原理:AE=EA^-1
* @param a
* @return
* @throws Exception
*/
public static Matrix inv(Matrix a) throws Exception {
if (!invable(a)) {
throw new Exception("矩阵不可逆");
}
// [a|E]
Matrix b = a.splice(1, eye(a.getMatrixRowCount()));
double[][] data = b.getMatrix();
int rowCount = b.getMatrixRowCount();
int colCount = b.getMatrixColCount();
//此处应用a的列数,为简化,直接用b的行数
for (int j = 0; j < rowCount; j++) {
//若遇到0则交换两行
int notZeroRow = -2;
if(data[j][j] == 0){
notZeroRow = -1;
for (int l = j; l < rowCount; l++) {
if (data[l][j] != 0) {
notZeroRow = l;
break;
}
}
}
if (notZeroRow == -1) {
throw new Exception("矩阵不可逆");
}else if(notZeroRow != -2){
//交换j与notZeroRow两行
double[] tmp = data[j];
data[j] = data[notZeroRow];
data[notZeroRow] = tmp;
}
//将第data[j][j]化为1
if (data[j][j] != 1) {
double multiple = data[j][j];
for (int colIdx = j; colIdx < colCount; colIdx++) {
data[j][colIdx] /= multiple;
}
}
//行与行相减
for (int i = 0; i < rowCount; i++) {
if (i != j) {
double multiple = data[i][j] / data[j][j];
//遍历行中的列
for (int k = j; k < colCount; k++) {
data[i][k] = data[i][k] - multiple * data[j][k];
}
}
}
}
Matrix result = new Matrix(data);
return result.subMatrix(0, rowCount, rowCount, rowCount);
}
/**
* 求矩阵的伴随矩阵
* 原理:A*=|A|A^-1
* @param a
* @return
* @throws Exception
*/
public static Matrix adj(Matrix a) throws Exception {
return inv(a).multiple(det(a));
}
/**
* 矩阵转成上三角矩阵
* @param a
* @return
* @throws Exception
*/
public static Matrix getTopTriangle(Matrix a) throws Exception {
if (!a.isSquareMatrix()) {
throw new Exception("不是方阵无法进行计算");
}
int matrixHeight = a.getMatrixRowCount();
double[][] result = a.getMatrix();
//遍历列
for (int j = 0; j < matrixHeight; j++) {
//遍历行
for (int i = j+1; i < matrixHeight; i++) {
//若遇到0则交换两行
int notZeroRow = -2;
if(result[j][j] == 0){
notZeroRow = -1;
for (int l = i; l < matrixHeight; l++) {
if (result[l][j] != 0) {
notZeroRow = l;
break;
}
}
}
if (notZeroRow == -1) {
throw new Exception("矩阵不可逆");
}else if(notZeroRow != -2){
//交换j与notZeroRow两行
double[] tmp = result[j];
result[j] = result[notZeroRow];
result[notZeroRow] = tmp;
}
double multiple = result[i][j]/result[j][j];
//遍历行中的列
for (int k = j; k < matrixHeight; k++) {
result[i][k] = result[i][k] - multiple * result[j][k];
}
}
}
return new Matrix(result);
}
/**
* 计算矩阵的行列式
* @param a
* @return
* @throws Exception
*/
public static double det(Matrix a) throws Exception {
//将矩阵转成上三角矩阵
Matrix b = MatrixUtil.getTopTriangle(a);
double result = 1;
//计算矩阵行列式
for (int i = 0; i < b.getMatrixRowCount(); i++) {
result *= b.getValOfIdx(i, i);
}
return result;
}
/**
* 获取协方差矩阵
* @param a
* @return
* @throws Exception
*/
public static Matrix cov(Matrix a) throws Exception {
if (a.getMatrix() == null) {
throw new Exception("矩阵为空");
}
Matrix avg = a.getColAvg().extend(2, a.getMatrixRowCount());
Matrix tmp = a.subtract(avg);
return tmp.transpose().multiple(tmp).multiple(1/((double) a.getMatrixRowCount() -1));
}
/**
* 判断矩阵是否可逆
* 如果可转为上三角矩阵则可逆
* @param a
* @return
*/
public static boolean invable(Matrix a) {
try {
getTopTriangle(a);
return true;
} catch (Exception e) {
return false;
}
}
/**
* 获取矩阵的特征值矩阵调用Jama中的getV方法
* @param a
* @return
*/
public static Matrix getV(Matrix a) {
EigenvalueDecomposition eig = new EigenvalueDecomposition(new Jama.Matrix(a.getMatrix()));
return new Matrix(eig.getV().getArray());
}
/**
* 取特征值实部
* @param a
* @return
*/
public double[] getRealEigenvalues(Matrix a){
EigenvalueDecomposition eig = new EigenvalueDecomposition(new Jama.Matrix(a.getMatrix()));
return eig.getRealEigenvalues();
}
/**
* 取特征值虚部
* @param a
* @return
*/
public double[] getImagEigenvalues(Matrix a){
EigenvalueDecomposition eig = new EigenvalueDecomposition(new Jama.Matrix(a.getMatrix()));
return eig.getImagEigenvalues();
}
/**
* 取块对角特征值矩阵
* @param a
* @return
*/
public static Matrix getD(Matrix a) {
EigenvalueDecomposition eig = new EigenvalueDecomposition(new Jama.Matrix(a.getMatrix()));
return new Matrix(eig.getD().getArray());
}
/**
* 数据归一化
* @param a 要归一化的数据
* @param normalizationMin 要归一化的区间下限
* @param normalizationMax 要归一化的区间上限
* @return
*/
public static Map<String, Object> normalize(Matrix a, double normalizationMin, double normalizationMax) throws Exception {
HashMap<String, Object> result = new HashMap<>();
double[][] maxArr = new double[1][a.getMatrixColCount()];
double[][] minArr = new double[1][a.getMatrixColCount()];
double[][] res = new double[a.getMatrixRowCount()][a.getMatrixColCount()];
for (int i = 0; i < a.getMatrixColCount(); i++) {
List tmp = new ArrayList();
for (int j = 0; j < a.getMatrixRowCount(); j++) {
tmp.add(a.getValOfIdx(j,i));
}
double max = (double) Collections.max(tmp);
double min = (double) Collections.min(tmp);
//数据归一化(注:若max与min均为0则不需要归一化)
if (max != 0 || min != 0) {
for (int j = 0; j < a.getMatrixRowCount(); j++) {
try {
if ((a.getValOfIdx(j,i) - min) == 0 || (max - min) == 0) {
res[j][i] = normalizationMin;
continue;
}
res[j][i] = normalizationMin + (a.getValOfIdx(j,i) - min) / (max - min) * (normalizationMax - normalizationMin);
} catch (IllegalArgumentException e) {
res[j][i] = 0;
}
}
}
maxArr[0][i] = max;
minArr[0][i] = min;
}
result.put("max", new Matrix(maxArr));
result.put("min", new Matrix(minArr));
result.put("res", new Matrix(res));
return result;
}
/**
* 反归一化
* @param a 要反归一化的数据
* @param normalizationMin 要反归一化的区间下限
* @param normalizationMax 要反归一化的区间上限
* @param dataMax 数据最大值
* @param dataMin 数据最小值
* @return
*/
public static Matrix inverseNormalize(Matrix a, double normalizationMax, double normalizationMin , Matrix dataMax,Matrix dataMin){
double[][] res = new double[a.getMatrixRowCount()][a.getMatrixColCount()];
for (int i = 0; i < a.getMatrixColCount(); i++) {
//数据反归一化
if (dataMin.getValOfIdx(0,i) != 0 || dataMax.getValOfIdx(0,i) != 0) {
for (int j = 0; j < a.getMatrixRowCount(); j++) {
if ((a.getValOfIdx(j,i) - normalizationMin) == 0 || (normalizationMax - normalizationMin) == 0) {
res[j][i] = dataMin.getValOfIdx(0,i);
continue;
}
res[j][i] = dataMin.getValOfIdx(0,i) + (dataMax.getValOfIdx(0,i) - dataMin.getValOfIdx(0,i)) * (a.getValOfIdx(j,i) - normalizationMin) / (normalizationMax - normalizationMin);
}
}
}
return new Matrix(res);
}
}

32
algorithm/src/main/java/com/mh/algorithm/utils/SerializationUtil.java

@ -0,0 +1,32 @@
package com.mh.algorithm.utils;
import java.io.*;
public class SerializationUtil {
/**
* 对象序列化到本地
* @param object
* @throws IOException
*/
public static void serialize(Object object, String path) throws IOException {
File file = new File(path);
System.out.println(file.getAbsolutePath());
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(file));
out.writeObject(object);
out.close();
}
/**
* 对象反序列化
* @return
* @throws IOException
* @throws ClassNotFoundException
*/
public static Object deSerialization(String path) throws IOException, ClassNotFoundException {
File file = new File(path);
ObjectInputStream oin = new ObjectInputStream(new FileInputStream(file));
Object object = oin.readObject();
oin.close();
return object;
}
}

71
algorithm/src/test/java/com/mh/algorithm/bpnn/bpnnTest.java

@ -0,0 +1,71 @@
package com.mh.algorithm.bpnn;
import com.mh.algorithm.matrix.Matrix;
import com.mh.algorithm.utils.CsvInfo;
import com.mh.algorithm.utils.CsvUtil;
import com.mh.algorithm.utils.SerializationUtil;
import org.junit.Test;
import java.util.Date;
public class bpnnTest {
@Test
public void test() throws Exception {
// 创建训练集矩阵
CsvInfo csvInfo = CsvUtil.getCsvInfo(true, "D:\\ljf\\my_pro\\top-algorithm-set-dev\\src\\trainDataElec.csv");
Matrix trainSet = csvInfo.toMatrix();
// 创建BPNN工厂对象
BPNeuralNetworkFactory factory = new BPNeuralNetworkFactory();
// 创建BP参数对象
BPParameter bpParameter = new BPParameter();
bpParameter.setInputLayerNeuronCount(2);
bpParameter.setHiddenLayerNeuronCount(2);
bpParameter.setOutputLayerNeuronCount(2);
bpParameter.setPrecision(0.01);
bpParameter.setMaxTimes(10000);
// 训练BP神经网络
System.out.println(new Date());
BPModel bpModel = factory.trainBP(bpParameter, trainSet);
System.out.println(new Date());
// 将BPModel序列化到本地
SerializationUtil.serialize(bpModel, "elec");
CsvInfo csvInfo2 = CsvUtil.getCsvInfo(true, "D:\\ljf\\my_pro\\top-algorithm-set-dev\\src\\testDataElec.csv");
Matrix testSet = csvInfo2.toMatrix();
Matrix testData1 = testSet.subMatrix(0, testSet.getMatrixRowCount(), 0, testSet.getMatrixColCount() - 2);
Matrix testLabel = testSet.subMatrix(0, testSet.getMatrixRowCount(), testSet.getMatrixColCount() - 2, 1);
// 将BPModel反序列化
BPModel bpModel1 = (BPModel) SerializationUtil.deSerialization("elec");
Matrix result = factory.computeBP(bpModel1, testData1);
int total = result.getMatrixRowCount();
int correct = 0;
for (int i = 0; i < result.getMatrixRowCount(); i++) {
if(Math.round(result.getValOfIdx(i,0)) == testLabel.getValOfIdx(i,0)){
correct++;
}
}
double correctRate = Double.valueOf(correct) / Double.valueOf(total);
System.out.println(correctRate);
}
/**
* 使用示例
* @throws Exception
*/
@Test
public void bpnnUsing() throws Exception{
CsvInfo csvInfo = CsvUtil.getCsvInfo(false, "D:\\ljf\\my_pro\\top-algorithm-set-dev\\src\\dataElec.csv");
Matrix data = csvInfo.toMatrix();
// 将BPModel反序列化
BPModel bpModel1 = (BPModel) SerializationUtil.deSerialization("elec");
// 创建工厂
BPNeuralNetworkFactory factory = new BPNeuralNetworkFactory();
Matrix result = factory.computeBP(bpModel1, data);
CsvUtil.createCsvFile(null,result,"D:\\ljf\\my_pro\\top-algorithm-set-dev\\src\\computeResult.csv");
}
}

46
algorithm/src/test/java/com/mh/algorithm/knn/knnTest.java

@ -0,0 +1,46 @@
//package com.mh.algorithm.knn;
//
//import com.mh.algorithm.matrix.Matrix;
//import com.mh.algorithm.utils.CsvInfo;
//import com.mh.algorithm.utils.CsvUtil;
//import com.mh.algorithm.utils.DoubleUtil;
//import org.junit.Test;
//
///**
// * @program: top-algorithm-set
// * @description:
// * @author: Mr.Zhao
// * @create: 2020-10-26 22:04
// **/
//public class knnTest {
// @Test
// public void test() throws Exception {
// // 训练集
// CsvInfo csvInfo = CsvUtil.getCsvInfo(false, "E:\\jarTest\\trainData.csv");
// Matrix trainSet = csvInfo.toMatrix();
// Matrix trainSetLabels = trainSet.getColOfIdx(trainSet.getMatrixColCount() - 1);
// Matrix trainSetData = trainSet.subMatrix(0, trainSet.getMatrixRowCount(), 0, trainSet.getMatrixColCount() - 1);
//
// CsvInfo csvInfo1 = CsvUtil.getCsvInfo(false, "E:\\jarTest\\testData.csv");
// Matrix testSet = csvInfo1.toMatrix();
// Matrix testSetData = trainSet.subMatrix(0, testSet.getMatrixRowCount(), 0, testSet.getMatrixColCount() - 1);
// Matrix testSetLabels = trainSet.getColOfIdx(testSet.getMatrixColCount() - 1);
//
// // 分类
// long startTime = System.currentTimeMillis();
// Matrix result = KNN.classify(testSetData, trainSetData, trainSetLabels, 5);
// long endTime = System.currentTimeMillis();
// System.out.println("run time:" + (endTime - startTime));
// // 正确率
// Matrix error = result.subtract(testSetLabels);
// int total = error.getMatrixRowCount();
// int correct = 0;
// for (int i = 0; i < error.getMatrixRowCount(); i++) {
// if (DoubleUtil.equals(error.getValOfIdx(i, 0), 0.0)) {
// correct++;
// }
// }
// double correctRate = Double.valueOf(correct) / Double.valueOf(total);
// System.out.println("correctRate:"+ correctRate);
// }
//}

26
common/pom.xml

@ -34,13 +34,24 @@
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.4.7</version>
</dependency>
<!-- web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.1.0</version>
<exclusions>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-to-slf4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- commons-beanutils -->
<dependency>
<groupId>commons-beanutils</groupId>
@ -59,12 +70,11 @@
<artifactId>commons-collections4</artifactId>
<version>4.4</version>
</dependency>
<!-- poi -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.4</version>
<version>4.1.2</version>
</dependency>
</dependencies>
</project>

26
common/src/main/java/com/mh/common/annotation/SysLogger.java

@ -1,13 +1,13 @@
package com.mh.common.annotation;
import java.lang.annotation.*;
/**
* Created by fangzhipeng on 2017/7/12.
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SysLogger {
String value() default "";
}
//package com.mh.common.annotation;
//
//import java.lang.annotation.*;
//
///**
// * Created by fangzhipeng on 2017/7/12.
// */
//@Target(ElementType.METHOD)
//@Retention(RetentionPolicy.RUNTIME)
//@Documented
//public @interface SysLogger {
// String value() default "";
//}

84
common/src/main/java/com/mh/common/utils/FileUtils.java

@ -1,42 +1,42 @@
package com.mh.common.utils;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
/**
* 文件相关操作
* @author Louis
* @date Jan 14, 2019
*/
public class FileUtils {
/**
* 下载文件
* @param response
* @param file
* @param newFileName
*/
public static void downloadFile(HttpServletResponse response, File file, String newFileName) {
try {
response.setHeader("Content-Disposition", "attachment; filename=" + new String(newFileName.getBytes("ISO-8859-1"), "UTF-8"));
BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
InputStream is = new FileInputStream(file.getAbsolutePath());
BufferedInputStream bis = new BufferedInputStream(is);
int length = 0;
byte[] temp = new byte[1 * 1024 * 10];
while ((length = bis.read(temp)) != -1) {
bos.write(temp, 0, length);
}
bos.flush();
bis.close();
bos.close();
is.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
//package com.mh.common.utils;
//
//import javax.servlet.http.HttpServletResponse;
//import java.io.BufferedInputStream;
//import java.io.BufferedOutputStream;
//import java.io.File;
//import java.io.FileInputStream;
//import java.io.InputStream;
//
///**
// * 文件相关操作
// * @author Louis
// * @date Jan 14, 2019
// */
//public class FileUtils {
//
// /**
// * 下载文件
// * @param response
// * @param file
// * @param newFileName
// */
// public static void downloadFile(HttpServletResponse response, File file, String newFileName) {
// try {
// response.setHeader("Content-Disposition", "attachment; filename=" + new String(newFileName.getBytes("ISO-8859-1"), "UTF-8"));
// BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
// InputStream is = new FileInputStream(file.getAbsolutePath());
// BufferedInputStream bis = new BufferedInputStream(is);
// int length = 0;
// byte[] temp = new byte[1 * 1024 * 10];
// while ((length = bis.read(temp)) != -1) {
// bos.write(temp, 0, length);
// }
// bos.flush();
// bis.close();
// bos.close();
// is.close();
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
//}

28
pom.xml

@ -11,6 +11,7 @@
<modules>
<module>common</module>
<module>user-service</module>
<module>algorithm</module>
</modules>
<parent>
@ -29,37 +30,10 @@
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jolokia</groupId>
<artifactId>jolokia-core</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
</dependency>
<!-- 添加consul依赖-->
<!-- <dependency>-->
<!-- <groupId>org.springframework.cloud</groupId>-->
<!-- <artifactId>spring-cloud-starter-consul-discovery</artifactId>-->
<!-- </dependency>-->
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.rxtx</groupId>
<artifactId>rxtx</artifactId>

86
user-service/pom.xml

@ -36,11 +36,11 @@
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-config -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
<version>2.2.2.RELEASE</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.cloud</groupId>-->
<!-- <artifactId>spring-cloud-starter-config</artifactId>-->
<!-- <version>2.2.2.RELEASE</version>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
@ -58,11 +58,6 @@
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.3.0</version>
</dependency>
<!-- &lt;!&ndash; mysql数据库链接&ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>mysql</groupId>-->
<!-- <artifactId>mysql-connector-java</artifactId>-->
<!-- </dependency>-->
<!-- druid配置-->
<dependency>
<groupId>com.alibaba</groupId>
@ -74,11 +69,6 @@
<artifactId>mssql-jdbc</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>5.0.0.Alpha2</version>
</dependency>
<!-- 登录验证码-->
<dependency>
<groupId>com.github.penggle</groupId>
@ -105,17 +95,22 @@
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- 添加consul依赖-->
<!-- <dependency>-->
<!-- <groupId>org.springframework.cloud</groupId>-->
<!-- <artifactId>spring-cloud-starter-consul-discovery</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
</dependency>
<!--spring-boot-admin -->
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop -->
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>2.2.2</version>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>
<!-- Lombok-->
<dependency>
@ -135,6 +130,49 @@
<artifactId>commons-pool2</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.github.ben-manes.caffeine/caffeine -->
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>2.8.8</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.4</version>
</dependency>
<!--解决高版本JDK问题-->
<!--javax.xml.bind.DatatypeConverter错误-->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
<!-- 算法包 -->
<dependency>
<groupId>com.mh</groupId>
<artifactId>algorithm</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>

3
user-service/src/main/java/com/mh/user/UserServiceApplication.java

@ -3,7 +3,6 @@ package com.mh.user;
import com.mh.user.job.CollectionLoopRunner;
import com.mh.user.serialport.SerialPortListener;
import com.mh.user.serialport.SerialPortUtil;
import com.mh.user.utils.TimedTask2;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
@ -27,7 +26,7 @@ public class UserServiceApplication extends SpringBootServletInitializer {
}
@PreDestroy
public void destory() {
public void destroy() {
//关闭应用前 关闭端口
SerialPortUtil serialPortUtil = SerialPortUtil.getSerialPortUtil();
serialPortUtil.removeListener(CollectionLoopRunner.serialPort, new SerialPortListener());

182
user-service/src/main/java/com/mh/user/aspect/DaoAspect.java

@ -1,91 +1,91 @@
package com.mh.user.aspect;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import com.mh.common.utils.StringUtils;
import com.mh.user.utils.SecurityUtils;
import org.apache.commons.beanutils.BeanUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
/**
* DAO切面插入创建人创建时间修改人修改时间
* @author Louis
* @date Oct 29, 2018
*/
@Aspect
@Component
@Configuration
public class DaoAspect {
private static final String createBy = "createBy";
private static final String createTime = "createTime";
private static final String lastUpdateBy = "lastUpdateBy";
private static final String lastUpdateTime = "lastUpdateTime";
@Pointcut("execution(* com.mh.*.mapper.*.update*(..))")
public void daoUpdate() {
}
@Pointcut("execution(* com.mh.*.mapper.*.insert*(..))")
public void daoCreate() {
}
@Around("daoUpdate()")
public Object doAroundUpdate(ProceedingJoinPoint pjp) throws Throwable {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (attributes == null) {
return pjp.proceed();
}
HttpServletRequest request = attributes.getRequest();
String token = request.getHeader("token");
String username = getUserName();
if (token != null && username != null) {
Object[] objects = pjp.getArgs();
if (objects != null && objects.length > 0) {
for (Object arg : objects) {
BeanUtils.setProperty(arg, lastUpdateBy, username);
BeanUtils.setProperty(arg, lastUpdateTime, new Date());
}
}
}
Object object = pjp.proceed();
return object;
}
@Around("daoCreate()")
public Object doAroundCreate(ProceedingJoinPoint pjp) throws Throwable {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (attributes == null) {
return pjp.proceed();
}
Object[] objects = pjp.getArgs();
if (objects != null && objects.length > 0) {
for (Object arg : objects) {
String username = getUserName();
if (username != null) {
if (StringUtils.isBlank(BeanUtils.getProperty(arg, createBy))) {
BeanUtils.setProperty(arg, createBy, username);
}
if (StringUtils.isBlank(BeanUtils.getProperty(arg, createTime))) {
BeanUtils.setProperty(arg, createTime, new Date());
}
}
}
}
Object object = pjp.proceed();
return object;
}
private String getUserName() {
return SecurityUtils.getUsername();
}
}
//package com.mh.user.aspect;
//
//import java.util.Date;
//
//import javax.servlet.http.HttpServletRequest;
//
//import com.mh.common.utils.StringUtils;
//import com.mh.user.utils.SecurityUtils;
//import org.apache.commons.beanutils.BeanUtils;
//import org.aspectj.lang.ProceedingJoinPoint;
//import org.aspectj.lang.annotation.Around;
//import org.aspectj.lang.annotation.Aspect;
//import org.aspectj.lang.annotation.Pointcut;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.stereotype.Component;
//import org.springframework.web.context.request.RequestContextHolder;
//import org.springframework.web.context.request.ServletRequestAttributes;
//
///**
// * DAO切面,插入创建人,创建时间,修改人,修改时间
// * @author Louis
// * @date Oct 29, 2018
// */
//@Aspect
//@Component
//@Configuration
//public class DaoAspect {
// private static final String createBy = "createBy";
// private static final String createTime = "createTime";
// private static final String lastUpdateBy = "lastUpdateBy";
// private static final String lastUpdateTime = "lastUpdateTime";
//
// @Pointcut("execution(* com.mh.*.mapper.*.update*(..))")
// public void daoUpdate() {
// }
//
// @Pointcut("execution(* com.mh.*.mapper.*.insert*(..))")
// public void daoCreate() {
// }
//
// @Around("daoUpdate()")
// public Object doAroundUpdate(ProceedingJoinPoint pjp) throws Throwable {
// ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
// if (attributes == null) {
// return pjp.proceed();
// }
// HttpServletRequest request = attributes.getRequest();
// String token = request.getHeader("token");
// String username = getUserName();
// if (token != null && username != null) {
// Object[] objects = pjp.getArgs();
// if (objects != null && objects.length > 0) {
// for (Object arg : objects) {
// BeanUtils.setProperty(arg, lastUpdateBy, username);
// BeanUtils.setProperty(arg, lastUpdateTime, new Date());
// }
// }
// }
// Object object = pjp.proceed();
// return object;
//
// }
//
// @Around("daoCreate()")
// public Object doAroundCreate(ProceedingJoinPoint pjp) throws Throwable {
// ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
// if (attributes == null) {
// return pjp.proceed();
// }
// Object[] objects = pjp.getArgs();
// if (objects != null && objects.length > 0) {
// for (Object arg : objects) {
// String username = getUserName();
// if (username != null) {
// if (StringUtils.isBlank(BeanUtils.getProperty(arg, createBy))) {
// BeanUtils.setProperty(arg, createBy, username);
// }
// if (StringUtils.isBlank(BeanUtils.getProperty(arg, createTime))) {
// BeanUtils.setProperty(arg, createTime, new Date());
// }
// }
// }
// }
// Object object = pjp.proceed();
// return object;
// }
//
// private String getUserName() {
// return SecurityUtils.getUsername();
// }
//}

2
user-service/src/main/java/com/mh/user/aspect/SysLogAspect.java

@ -16,6 +16,7 @@ import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
@ -27,6 +28,7 @@ import java.util.Date;
*/
@Aspect
@Component
@Lazy(value = false)
public class SysLogAspect {
@Autowired

59
user-service/src/main/java/com/mh/user/config/CaffeineCacheConfig.java

@ -0,0 +1,59 @@
package com.mh.user.config;
import com.github.benmanes.caffeine.cache.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.TimeUnit;
/**
* @author LJF
* @title
* @description 使用caffeine缓存技术
* @updateTime 2020-12-15
* @throws
*/
@Configuration
public class CaffeineCacheConfig {
// 软引用: 如果一个对象只具有软引用,则内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。
// 弱引用: 弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,
// 不管当前内存空间足够与否,都会回收它的内存
@Bean(name = "caffeineCache")
public Cache<String, Object> caffeineCache() {
return Caffeine.newBuilder()
// 软引用
.softValues()
// 弱引用
// .weakValues()
// 设置最后一次写入或访问后经过固定时间过期
.expireAfterWrite(8*60*60, TimeUnit.SECONDS)
// 初始的缓存空间大小
.initialCapacity(100)
// 缓存的最大条数
.maximumSize(1000)
.build();
}
//定义缓存,可直接使用
@Bean
public LoadingCache expiryCache(){
LoadingCache<String, Object> loadingCache = Caffeine.newBuilder()
.initialCapacity(100)
.maximumSize(1000)
//缓存写入/删除监控
.writer(new CacheWriter<Object, Object>() {
@Override
public void write(Object key, Object value) { //此方法是同步阻塞的
System.out.println("--缓存写入--:key=" + key + ", value=" + value);
}
@Override
public void delete(Object key, Object value, RemovalCause cause) { System.out.println("--缓存删除--:key=" + key); }
})
.expireAfterAccess(6, TimeUnit.HOURS) //过期时间
.build((String key)->"刷新的数据"); //cacheload实现类,刷新时候调用
// loadingCache.put("name","侯征");
return loadingCache;
}
}

1
user-service/src/main/java/com/mh/user/config/QuartzConfig.java

@ -1,7 +1,6 @@
package com.mh.user.config;
import com.mh.user.job.JobFactory;
import com.mh.user.utils.TimedTask2;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Scheduler;
import org.springframework.context.annotation.Bean;

12
user-service/src/main/java/com/mh/user/config/RestTemplateConfig.java

@ -1,14 +1,22 @@
package com.mh.user.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
* @author ljf
* @author LJF
* @title
* @description redis配置
* @description 请求数据
* @updateTime 2020-08-20
* @throws
*/
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}

47
user-service/src/main/java/com/mh/user/constants/Constant.java

@ -9,9 +9,50 @@ package com.mh.user.constants;
*/
public class Constant {
public static boolean CONTROL_WEB_FLAG = false;
public static final CharSequence CUSTOM_NAME_HUAXIA = "华夏";
public static final CharSequence CUSTOM_NAME_GUANGSHANG = "广商";
public static final String WEATHER_DATA = "weather_data";
public static boolean CONTROL_WEB_FLAG = false;
public static boolean SEND_STATUS = false; // 指令发送状态
public static boolean FLAG = false;
public static boolean WEB_FLAG = false; // 判断是否有前端指令下发
public static volatile boolean FLAG = false;
public static volatile boolean WEB_FLAG = false; // 判断是否有前端指令下发
public static final String FAIL = "fail";
public static final String SUCCESS = "success";
public static final String READ = "0";
public static final String WRITE = "1";
// 远向设备寄存器地址判断:0010:供回水状态;0017-0018:热泵状态
public static final String REG_ADDR_0018 = "0018";
public static final String REG_ADDR_0017 = "0017";
public static final String REG_ADDR_0010 = "0010";
public static final String BRAND_AU_SUN = "澳升";
public static final String BRAND_RU_YI = "汝翊";
public static final String BRAND_MEI_DI = "美的";
public static final String BRAND_MEI_DI_TWO = "美的2";
public static final String BRAND_RUI_XING = "瑞星";
public static final String BRAND_HAI_ER = "海尔";
public static final String BRAND_YUAN_XIANG = "远向";
public static final String BRAND_DING_WEI = "顶威";
public static final String BRAND_ZHONG_KAI = "中凯";
private static final String RUNNING = "运行";
private static final String NOT_RUNNING = "不运行";
}

59
user-service/src/main/java/com/mh/user/constants/DeviceEnum.java

@ -0,0 +1,59 @@
package com.mh.user.constants;
import com.mh.user.factory.*;
/**
* @author LJF
* @version 1.0
* @project CHWS
* @description 设备枚举类
* @date 2024-03-19 10:06:29
*/
public enum DeviceEnum {
WtMeterEnum("水表", WtMeter.getInstance()),
EleMeterEnum("电表", EleMeter.getInstance()),
PressureTransEnum("压变", PressureTrans.getInstance()),
HeatPumpEnum("热泵", HeatPump.getInstance()),
TempControlEnum("温控", TempControl.getInstance()),
TimeControlEnum("时控", TimeControl.getInstance()),
WaterLevelSwitchEnum("水位开关", WaterLevelSwitch.getInstance()),
StatusCheckEnum("状态检测", StatusCheck.getInstance()),
TempTransEnum("温度变送器", TempTrans.getInstance()),
HeatPumpStatusEnum("热泵状态", HeatPumpStatus.getInstance());
private String deviceType;
private Device device;
private
DeviceEnum(String deviceType, Device device) {
this.deviceType = deviceType;
this.device = device;
}
public String getDeviceType() {
return deviceType;
}
public void setDeviceType(String deviceType) {
this.deviceType = deviceType;
}
public Device getDevice() {
return device;
}
public void setDevice(Device device) {
this.device = device;
}
public static Device getDevice(String deviceType) {
for (DeviceEnum deviceEnum : DeviceEnum.values()) {
if (deviceEnum.getDeviceType().equals(deviceType)) {
return deviceEnum.getDevice();
}
}
return null;
}
}

59
user-service/src/main/java/com/mh/user/constants/DeviceStrategyEnum.java

@ -0,0 +1,59 @@
package com.mh.user.constants;
import com.mh.user.factory.*;
import com.mh.user.strategy.*;
/**
* @author LJF
* @version 1.0
* @project CHWS
* @description 设备枚举类
* @date 2024-03-19 10:06:29
*/
public enum DeviceStrategyEnum {
WtMeterEnum("水表", WtMeterStrategy.getInstance()),
EleMeterEnum("电表", EleMeterStrategy.getInstance()),
PressureTransEnum("压变", PressureTransStrategy.getInstance()),
HeatPumpEnum("热泵", HeatPumpStrategy.getInstance()),
TempControlEnum("温控", TempControlStrategy.getInstance()),
TimeControlEnum("时控", TimeControlStrategy.getInstance()),
WaterLevelSwitchEnum("水位开关", WaterLevelSwitchStrategy.getInstance()),
StatusCheckEnum("状态检测", StatusCheckStrategy.getInstance()),
TempTransEnum("温度变送器", TempTransStrategy.getInstance()),
HeatPumpStatusEnum("热泵状态", HeatPumpStatusStrategy.getInstance());
private String deviceType;
private DeviceStrategy deviceStrategy;
private DeviceStrategyEnum(String deviceType, DeviceStrategy deviceStrategy) {
this.deviceType = deviceType;
this.deviceStrategy = deviceStrategy;
}
public String getDeviceType() {
return deviceType;
}
public void setDeviceType(String deviceType) {
this.deviceType = deviceType;
}
public DeviceStrategy getDeviceStrategy() {
return deviceStrategy;
}
public void setDeviceStrategy(DeviceStrategy deviceStrategy) {
this.deviceStrategy = deviceStrategy;
}
public static DeviceStrategy getDeviceStrategy(String deviceType) {
for (DeviceStrategyEnum deviceEnum : DeviceStrategyEnum.values()) {
if (deviceEnum.getDeviceType().equals(deviceType)) {
return deviceEnum.getDeviceStrategy();
}
}
return null;
}
}

2
user-service/src/main/java/com/mh/user/controller/AnalysisController.java

@ -39,7 +39,7 @@ public class AnalysisController {
}
@PostMapping("/queryMonth") //type=1(水),2(电),3(能耗)
@PostMapping("/queryMonth") //type=1(水),2(电),3(能耗),4(维保),5(使用时间)
public HttpResult queryAnalysisMonth(@RequestParam(value = "curDate",required = true) String curDate,
@RequestParam(value = "buildingId",required = true) String buildingId,
@RequestParam(value = "type",defaultValue = "3") int type) {

26
user-service/src/main/java/com/mh/user/controller/BuildingController.java

@ -78,14 +78,14 @@ public class BuildingController {
// 删除多
@PostMapping(value="/deletes")
public HttpResult delete(@RequestBody List<BuildingEntity> records) {
public HttpResult deleteDevices(@RequestBody List<BuildingEntity> records) {
return HttpResult.ok(buildingService.deleteBuilding(records));
}
// 删除单个
@SysLogger(title="楼栋信息",optDesc = "删除楼栋信息")
@PostMapping(value="/delete")
public HttpResult delete(@RequestParam String id ) {
public HttpResult deleteDevice(@RequestParam String id ) {
return HttpResult.ok(buildingService.deleteBuilding(id));
}
@ -172,6 +172,15 @@ public class BuildingController {
case 6 :
rolName = "实际入住数";
break;
case 7 :
rolName = "水箱高度";
break;
case 8 :
rolName = "水箱高度(低区)";
break;
case 9 :
rolName = "热泵个数";
break;
}
if ((rol >= 1)&&(rol <= 4)&&(sCell.equals(""))){
msg = rolName + "不能为空" ;
@ -184,11 +193,14 @@ public class BuildingController {
// 创建实体类
BuildingEntity uploadEntity = new BuildingEntity();
uploadEntity.setBuildingName(deviceList.get(0));//楼栋名称
uploadEntity.setLevelsCount(Integer.parseInt(deviceList.get(1))); //楼层数
uploadEntity.setBeginLevel(Integer.parseInt(deviceList.get(2))); //起始楼层
uploadEntity.setHouseCount(Integer.parseInt(deviceList.get(3))); //每层宿舍数
uploadEntity.setBedCount(Integer.parseInt(deviceList.get(4))); //床位数
uploadEntity.setCheckInCount(Integer.parseInt(deviceList.get(5))); //实际入住数
uploadEntity.setLevelsCount(Integer.parseInt(deviceList.get(1))); //楼层数
uploadEntity.setBeginLevel(Integer.parseInt(deviceList.get(2))); //起始楼层
uploadEntity.setHouseCount(Integer.parseInt(deviceList.get(3))); //每层宿舍数
uploadEntity.setBedCount(Integer.parseInt(deviceList.get(4))); //床位数
uploadEntity.setCheckInCount(Integer.parseInt(deviceList.get(5))); //实际入住数
uploadEntity.setTankHeight(Double.parseDouble(deviceList.get(6))); //默认(高区)水箱高度
uploadEntity.setLowTankHeight(Double.parseDouble(deviceList.get(7))); //低区水箱高度
uploadEntity.setPumpCount(Integer.parseInt(deviceList.get(8))); //热泵个数
deviceList.clear();

6
user-service/src/main/java/com/mh/user/controller/ControlSetController.java

@ -46,11 +46,11 @@ public class ControlSetController {
}
//查询设置表
@SysLogger(title="控制设置",optDesc = "查询设置值")
@SysLogger(title="控制设置",optDesc = "查询时控设置值")
@PostMapping(value="/query")
public HttpResult queryControlSet(@RequestParam("buildingId") String buildingId) {
public HttpResult queryControlSet(@RequestParam("buildingId") String buildingId, @RequestParam(value = "timeName",required = false) String timeName) {
try{
ControlSetEntity control=controlSetService.queryControlSet(buildingId);
ControlSetEntity control=controlSetService.queryControlSet(buildingId, timeName);
return HttpResult.ok(control);
}catch (Exception e){
// e.printStackTrace();

8
user-service/src/main/java/com/mh/user/controller/DeviceFloorController.java

@ -7,7 +7,6 @@ import com.mh.user.entity.*;
import com.mh.user.model.DeviceModel;
import com.mh.user.service.BuildingService;
import com.mh.user.service.DeviceFloorService;
import com.mh.user.service.DeviceInstallService;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
@ -19,12 +18,9 @@ import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("floor")
@ -87,9 +83,9 @@ public class DeviceFloorController {
}
// 删除单个
@SysLogger(title="楼面设备",optDesc = "删除楼面设备信息")
@PostMapping(value="/delete")
public HttpResult delete(@RequestParam String id ) {
@SysLogger(title="楼面设备",optDesc = "删除楼面设备信息")
public HttpResult deleteDevice(@RequestParam String id ) {
return HttpResult.ok(deviceFloorService.deleteDevice(id));
}

32
user-service/src/main/java/com/mh/user/controller/DeviceInstallController.java

@ -1,6 +1,7 @@
package com.mh.user.controller;
import com.mh.common.http.HttpResult;
import com.mh.common.utils.StringUtils;
import com.mh.user.annotation.BusinessType;
import com.mh.user.annotation.SysLogger;
import com.mh.user.entity.BuildingEntity;
@ -51,9 +52,20 @@ public class DeviceInstallController {
@SysLogger(title="基表信息",optDesc = "修改基表信息")
@PostMapping(value="/update")
public HttpResult updateDevice(@RequestBody DeviceInstallEntity deviceInstallEntity) {
// 根据id查询对应的deviceInstall
DeviceInstallEntity oldEntity = deviceInstallService.selectDeviceById(deviceInstallEntity.getId());
// 删除全部的device_code_param值
deviceInstallService.deleteParamCode(oldEntity);
// 设置校验位
if (StringUtils.isBlank(deviceInstallEntity.getParity())) {
deviceInstallEntity.setParity(oldEntity.getParity());
}
// 在创建新的device_code_param值
deviceInstallService.createParamCode(deviceInstallEntity);
// 更新device_install
deviceInstallService.updateDevice(deviceInstallEntity);
String isUse="";
if (deviceInstallEntity.isUse()==true){
if (deviceInstallEntity.isUse()){
isUse="1";
}else{
isUse="0";
@ -80,14 +92,14 @@ public class DeviceInstallController {
// 删除多
@PostMapping(value="/deletes")
public HttpResult delete(@RequestBody List<DeviceInstallEntity> records) {
public HttpResult deleteDevices(@RequestBody List<DeviceInstallEntity> records) {
return HttpResult.ok(deviceInstallService.deleteDevice(records));
}
// 删除单个
@SysLogger(title="基表信息",optDesc = "删除基表信息")
@PostMapping(value="/delete")
public HttpResult delete(@RequestParam String id ) {
public HttpResult deleteDevice(@RequestParam String id ) {
return HttpResult.ok(deviceInstallService.deleteDevice(id));
}
@ -347,4 +359,18 @@ public class DeviceInstallController {
return HttpResult.ok("success",data);
}
@PostMapping(value = "/calibration")
public HttpResult calibration(@RequestParam(value = "buildingId") Integer buildingId,
@RequestParam(value = "deviceType") Integer deviceType,
@RequestParam(value = "param") Integer param,
@RequestParam(value = "readValue") String readValue,
@RequestParam(value = "realValue") String realValue) {
boolean isUpdate = deviceInstallService.updateDeviation(buildingId,deviceType,param,readValue,realValue);
if (isUpdate) {
return HttpResult.ok("success");
} else {
return HttpResult.error();
}
}
}

94
user-service/src/main/java/com/mh/user/controller/DeviceOperateController.java

@ -0,0 +1,94 @@
package com.mh.user.controller;
import com.alibaba.fastjson2.JSONObject;
import com.mh.common.http.HttpResult;
import com.mh.common.utils.StringUtils;
import com.mh.user.annotation.SysLogger;
import com.mh.user.constants.Constant;
import com.mh.user.entity.ControlSetEntity;
import com.mh.user.entity.DeviceCodeParamEntity;
import com.mh.user.entity.DeviceInstallEntity;
import com.mh.user.entity.PumpSetEntity;
import com.mh.user.model.DeviceModel;
import com.mh.user.model.SerialPortModel;
import com.mh.user.serialport.SerialPortSingle2;
import com.mh.user.service.*;
import com.mh.user.utils.ExchangeStringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
@Slf4j
@RestController
@RequestMapping("serial")
public class DeviceOperateController {
@Autowired
DeviceInstallService deviceInstallService;
@Autowired
PumpSetService pumpSetService;
@Autowired
ControlSetService controlSetService;
@Autowired
NowDataService nowDataService;
@Autowired
private DeviceControlService deviceControlService;
//操作设备
@SysLogger(title = "控制管理", optDesc = "设置设备参数值")
@PostMapping(value = "/operate")
public HttpResult operateDevice(@RequestBody List<SerialPortModel> params) {
try {
Constant.WEB_FLAG = true; //单抄,暂时停止采集
Thread.sleep(1000);
String returnStr = deviceControlService.readOrWriteDevice(params, Constant.WRITE);
if (!StringUtils.isBlank(returnStr) && "fail".equals(returnStr)) {
return HttpResult.error(500, "fail");
}
Constant.WEB_FLAG = false; //单抄,恢复采集
return HttpResult.ok();
} catch (Exception e) {
log.error("前端发送控制异常==>", e);
Constant.WEB_FLAG = false; //单抄,恢复采集
return HttpResult.error(500, "fail");
} finally {
Constant.WEB_FLAG = false;
}
}
//读数据
@SysLogger(title = "控制管理", optDesc = "读设备数据")
@PostMapping(value = "/read")
public HttpResult readData(@RequestBody List<SerialPortModel> params) {
try {
Constant.WEB_FLAG = true; //单抄,暂时停止采集
Thread.sleep(1000);
String rtData = deviceControlService.readOrWriteDevice(params, Constant.READ);
if (ExchangeStringUtil.getJSONType(rtData)) {
Map map = JSONObject.parseObject(rtData);
return HttpResult.ok("success", map);
} else {
if (rtData.equals("fail")) {
return HttpResult.error(500, "fail");
} else {
return HttpResult.ok(rtData, rtData);
}
}
} catch (Exception e) {
Constant.WEB_FLAG = false; //单抄,恢复采集
return HttpResult.error(500, "fail");
} finally {
Constant.WEB_FLAG = false; //单抄,恢复采集
}
}
}

36
user-service/src/main/java/com/mh/user/controller/EnergyPreController.java

@ -0,0 +1,36 @@
package com.mh.user.controller;
import com.mh.common.http.HttpResult;
import com.mh.user.dto.EnergyPreDTO;
import com.mh.user.service.HistoryDataPreService;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* @author LJF
* @version 1.0
* @project CHWS
* @description 用能预测controller
* @date 2024-05-09 17:24:48
*/
@RestController
@RequestMapping("/energyPre")
public class EnergyPreController {
@Resource
private HistoryDataPreService historyDataPreService;
@PostMapping("/topData")
public HttpResult getTopData(String buildingId, String type) {
return HttpResult.ok(historyDataPreService.getTopData(buildingId, type));
}
@PostMapping("/echartData")
public HttpResult getEnergyPre(String buildingId, String beginDate, String endDate, String type) {
return HttpResult.ok(historyDataPreService.getEnergyPre(buildingId, beginDate, endDate, type));
}
}

63
user-service/src/main/java/com/mh/user/controller/KnowledgeDataController.java

@ -0,0 +1,63 @@
package com.mh.user.controller;
import com.mh.common.http.HttpResult;
import com.mh.common.page.PageRequest;
import com.mh.common.page.PageResult;
import com.mh.user.entity.KnowledgeDataEntity;
import com.mh.user.service.KnowledgeDataService;
import io.jsonwebtoken.lang.Assert;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
/**
* @author LJF
* @version 1.0
* @project CHWS
* @description 知识库管理
* @date 2024-06-26 14:39:24
*/
@RestController
@RequestMapping("/knowledge")
public class KnowledgeDataController {
@Resource
private KnowledgeDataService knowledgeDataService;
@GetMapping("/query")
public HttpResult queryKnowledgeData(@RequestParam("pageNum") int pageNum, @RequestParam("pageSize") int pageSize) {
PageRequest pageRequest = new PageRequest();
pageRequest.setPageNum(pageNum);
pageRequest.setPageSize(pageSize);
return HttpResult.ok(knowledgeDataService.queryKnowledgeData(pageRequest));
}
@GetMapping("/{id}")
public HttpResult detail(@PathVariable(name = "id") Long id) {
KnowledgeDataEntity knowledgeData = knowledgeDataService.getById(id);
Assert.notNull(knowledgeData, "该文章已被删除");
return HttpResult.ok(knowledgeData);
}
@PostMapping("/update")
public HttpResult updateData(@Validated @RequestBody KnowledgeDataEntity knowledgeData) {
try {
knowledgeDataService.updateData(knowledgeData);
} catch (Exception e) {
throw new RuntimeException(e);
}
return HttpResult.ok();
}
@PostMapping("/insert")
public HttpResult insertKnowledgeData(@Validated @RequestBody KnowledgeDataEntity knowledgeData) {
try {
knowledgeDataService.insertKnowledgeData(knowledgeData);
} catch (Exception e) {
throw new RuntimeException(e);
}
return HttpResult.ok();
}
}

627
user-service/src/main/java/com/mh/user/controller/SerialPortController.java

@ -2,6 +2,7 @@ package com.mh.user.controller;
import com.alibaba.fastjson2.JSONObject;
import com.mh.common.http.HttpResult;
import com.mh.common.utils.StringUtils;
import com.mh.user.annotation.SysLogger;
import com.mh.user.constants.Constant;
import com.mh.user.entity.ControlSetEntity;
@ -10,8 +11,7 @@ import com.mh.user.entity.DeviceInstallEntity;
import com.mh.user.entity.PumpSetEntity;
import com.mh.user.model.DeviceModel;
import com.mh.user.model.SerialPortModel;
import com.mh.user.serialport.SerialPortSendReceive;
import com.mh.user.serialport.SerialPortSingle;
import com.mh.user.serialport.SerialPortSingle2;
import com.mh.user.service.ControlSetService;
import com.mh.user.service.DeviceInstallService;
import com.mh.user.service.NowDataService;
@ -21,6 +21,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
@ -42,297 +43,304 @@ public class SerialPortController {
NowDataService nowDataService;
//操作设备
@SysLogger(title="控制管理",optDesc = "设置设备参数值")
@PostMapping(value="/operate")
public HttpResult operateDevice(@RequestBody List<SerialPortModel> params){
try{
SerialPortSingle serialPortSingle = new SerialPortSingle(); //发送接收类
DeviceCodeParamEntity deviceCodeParam=new DeviceCodeParamEntity();//参数实体类
@SysLogger(title = "控制管理", optDesc = "设置设备参数值")
@PostMapping(value = "/operate/old")
public HttpResult operateDevice(@RequestBody List<SerialPortModel> params) {
try {
SerialPortSingle2 serialPortSingle = new SerialPortSingle2(); //发送接收类
DeviceCodeParamEntity deviceCodeParam = new DeviceCodeParamEntity();//参数实体类
Constant.WEB_FLAG=true; //单抄,暂时停止采集
Constant.WEB_FLAG = true; //单抄,暂时停止采集
for (SerialPortModel serialPortModel :
params) {
String deviceAddr=serialPortModel.getDeviceAddr();//设备通讯地址
String deviceType=serialPortModel.getDeviceType();//设备类型
String buildingId=serialPortModel.getBuildingId();//楼栋
String param=serialPortModel.getParam();//操作参数
if (deviceAddr==null || deviceAddr=="" ){
List<DeviceModel> list=deviceInstallService.selectDevices(buildingId,deviceType);
deviceAddr=list.get(0).getDeviceAddr();
String deviceAddr = serialPortModel.getDeviceAddr();//设备通讯地址
String deviceType = serialPortModel.getDeviceType();//设备类型
String buildingId = serialPortModel.getBuildingId();//楼栋
String param = serialPortModel.getParam();//操作参数
if (deviceAddr == null || deviceAddr.equals("")) {
List<DeviceModel> list = deviceInstallService.selectDevices(buildingId, deviceType);
deviceAddr = list.get(0).getDeviceAddr();
}
if(deviceAddr!=null && deviceAddr.length()>0){
DeviceInstallEntity deviceInstallEntity=deviceInstallService.selectDevice(deviceAddr,deviceType,buildingId);
//发送指令实体类
deviceCodeParam.setDeviceAddr(deviceAddr); //传入通讯编号
deviceCodeParam.setDeviceType(deviceType);
deviceCodeParam.setDataCom(deviceInstallEntity.getDataCom());
deviceCodeParam.setBaudrate(deviceInstallEntity.getBaudRate());
deviceCodeParam.setParity(deviceInstallEntity.getParity());
deviceCodeParam.setDataValue(serialPortModel.getDataValue());//传入相关参数值
deviceCodeParam.setBuildingId(buildingId);
String brand=deviceInstallEntity.getBrand();//品牌
deviceCodeParam.setBrand(brand);
ControlSetEntity controlData=new ControlSetEntity();
//设置设备实体对象
controlData.setBuildingId(deviceInstallEntity.getBuildingId());
if (deviceAddr == null || deviceAddr.length() == 0) {
Constant.WEB_FLAG = false;
return HttpResult.error("通讯ID为空!");
}
DeviceInstallEntity deviceInstallEntity = deviceInstallService.selectDevice(deviceAddr, deviceType, buildingId);
//发送指令实体类
deviceCodeParam.setDeviceAddr(deviceAddr); //传入通讯编号
deviceCodeParam.setDeviceType(deviceType);
deviceCodeParam.setDataCom(deviceInstallEntity.getDataCom());
deviceCodeParam.setBaudrate(deviceInstallEntity.getBaudRate());
deviceCodeParam.setParity(deviceInstallEntity.getParity());
deviceCodeParam.setDataValue(serialPortModel.getDataValue());//传入相关参数值
deviceCodeParam.setBuildingId(buildingId);
String brand = deviceInstallEntity.getBrand();//品牌
deviceCodeParam.setBrand(brand);
//设置设备实体对象
ControlSetEntity controlData = new ControlSetEntity();
controlData.setBuildingId(deviceInstallEntity.getBuildingId());
if (deviceType == null || deviceType.equals("") || deviceType.equals("热泵")) {
//设置热泵实体对象
PumpSetEntity pumpData = new PumpSetEntity();
pumpData.setBuildingId(deviceInstallEntity.getBuildingId());
pumpData.setPumpId(deviceAddr);
if (param == null || param.equals("") || param.equals("温度设定")) {
//发送指令
if (brand.equals("美的")) {
deviceCodeParam.setRegisterAddr("0642"); //寄存器地址
deviceCodeParam.setFunCode("10"); //功能码写数据
} else {
deviceCodeParam.setRegisterAddr("0003"); //寄存器地址
deviceCodeParam.setFunCode("06"); //功能码写数据
}
//保存数据
pumpData.setTempSet(serialPortModel.getDataValue());
pumpSetService.savePumpSet(pumpData);//热泵信息保存数据库
if (deviceType==null || deviceType.equals("") || deviceType.equals("热泵")){
//设置热泵实体对象
PumpSetEntity pumpData=new PumpSetEntity();
pumpData.setBuildingId(deviceInstallEntity.getBuildingId());
pumpData.setPumpId(deviceAddr);
if (param==null || param.equals("") || param.equals("温度设定")){
nowDataService.upTempSet2(buildingId, serialPortModel.getDataValue(), deviceAddr);//更新实时状态表
log.info("楼栋编号:" + buildingId + ",设定温度:" + serialPortModel.getDataValue() + ",热泵编号:" + deviceAddr);
} else if (param.equals("时段1")) {
if (brand.equals("美的")) {
//发送指令
if (brand.equals("美的")){
deviceCodeParam.setRegisterAddr("0642"); //寄存器地址
deviceCodeParam.setFunCode("10"); //功能码写数据
}else{
deviceCodeParam.setRegisterAddr("0003"); //寄存器地址
deviceCodeParam.setFunCode("06"); //功能码写数据
}
deviceCodeParam.setRegisterAddr("0656"); //寄存器地址
deviceCodeParam.setFunCode("10"); //功能码写数据
//保存数据
pumpData.setTempSet(serialPortModel.getDataValue());
pumpSetService.savePumpSet(pumpData);//热泵信息保存数据库
nowDataService.upTempSet2(buildingId,serialPortModel.getDataValue(),deviceAddr);//更新实时状态表
log.info("楼栋编号:"+buildingId+",设定温度:"+serialPortModel.getDataValue()+",热泵编号:"+deviceAddr);
}else if(param.equals("时段1")){
if (brand.equals("美的")) {
//发送指令
deviceCodeParam.setRegisterAddr("0656"); //寄存器地址
deviceCodeParam.setFunCode("10"); //功能码写数据
//保存数据
String time=serialPortModel.getDataValue();
if (time.length()==8){
String statTime=time.substring(0,2)+":"+time.substring(2,4);
String closeTime=time.substring(4,6)+":"+time.substring(6,8);
pumpData.setStartTime1(statTime);
pumpData.setCloseTime1(closeTime);
}
pumpSetService.savePumpSet(pumpData);//热泵信息保存数据库
}
}else if(param.equals("时段2")){
if (brand.equals("美的")) {
//发送指令
deviceCodeParam.setRegisterAddr("065A"); //寄存器地址
deviceCodeParam.setFunCode("10"); //功能码写数据
//保存数据
String time=serialPortModel.getDataValue();
if (time.length()==8){
String statTime=time.substring(0,2)+":"+time.substring(2,4);
String closeTime=time.substring(4,6)+":"+time.substring(6,8);
pumpData.setStartTime2(statTime);
pumpData.setCloseTime2(closeTime);
}
pumpSetService.savePumpSet(pumpData);//热泵信息保存数据库
String time = serialPortModel.getDataValue();
if (time.length() == 8) {
String statTime = time.substring(0, 2) + ":" + time.substring(2, 4);
String closeTime = time.substring(4, 6) + ":" + time.substring(6, 8);
pumpData.setStartTime1(statTime);
pumpData.setCloseTime1(closeTime);
}
pumpSetService.savePumpSet(pumpData);//热泵信息保存数据库
}
}else if (deviceType.equals("时控")){
deviceCodeParam.setFunCode("10"); //功能码写数据
String time=serialPortModel.getDataValue();
if (time.length()==16){
//时段1 HHmmHHmm
String statTime1=time.substring(0,2)+":"+time.substring(2,4); //HH:mm
String closeTime1=time.substring(4,6)+":"+time.substring(6,8); //HH:mm
//时段2
String statTime2=time.substring(8,10)+":"+time.substring(10,12);
String closeTime2=time.substring(12,14)+":"+time.substring(14,16);
if(param.equals("L1")){
deviceCodeParam.setRegisterAddr("0009"); //寄存器地址,L3路,L1(0009),L2(000D)
controlData.setUseStartTime1(statTime1);
controlData.setUseCloseTime1(closeTime1);
controlData.setUseStartTime2(statTime2);
controlData.setUseCloseTime2(closeTime2);
}else if(param.equals("L2")){
deviceCodeParam.setRegisterAddr("000D");
controlData.setUseStartTime3(statTime1);
controlData.setUseCloseTime3(closeTime1);
controlData.setUseStartTime4(statTime2);
controlData.setUseCloseTime4(closeTime2);
}else{
deviceCodeParam.setRegisterAddr("0011");
controlData.setUseStartTime5(statTime1);
controlData.setUseCloseTime5(closeTime1);
controlData.setUseStartTime6(statTime2);
controlData.setUseCloseTime6(closeTime2);
} else if (param.equals("时段2")) {
if (brand.equals("美的")) {
//发送指令
deviceCodeParam.setRegisterAddr("065A"); //寄存器地址
deviceCodeParam.setFunCode("10"); //功能码写数据
//保存数据
String time = serialPortModel.getDataValue();
if (time.length() == 8) {
String statTime = time.substring(0, 2) + ":" + time.substring(2, 4);
String closeTime = time.substring(4, 6) + ":" + time.substring(6, 8);
pumpData.setStartTime2(statTime);
pumpData.setCloseTime2(closeTime);
}
pumpSetService.savePumpSet(pumpData);//热泵信息保存数据库
}
controlSetService.saveControlSet(controlData); //保存设置内容
}else if (deviceType.equals("水位开关")){
if (brand==null || brand.equals("") || brand.equals("中凯")){//品牌
deviceCodeParam.setFunCode("12"); //功能码写数据
if (!serialPortModel.getDataValue().equals("100%")){
deviceCodeParam.setDataValue("100%");
serialPortSingle.serialPortSend(deviceCodeParam);//生成并发送指令
Thread.sleep(1500);
}
}else if(brand.equals("远向")){
deviceCodeParam.setFunCode("06"); //功能码写数据
if (!serialPortModel.getDataValue().equals("100%")){
deviceCodeParam.setDataValue("100%");
serialPortSingle.serialPortSend(deviceCodeParam);//生成并发送指令
Thread.sleep(1500);
}
}else if(brand.equals("顶威")){
deviceCodeParam.setFunCode("0407"); //功能码写数据
}
} else if (deviceType.equals("时控")) {
deviceCodeParam.setFunCode("10"); //功能码写数据
String time = serialPortModel.getDataValue();
if (time.length() == 16) {
//时段1 HHmmHHmm
String statTime1 = time.substring(0, 2) + ":" + time.substring(2, 4); //HH:mm
String closeTime1 = time.substring(4, 6) + ":" + time.substring(6, 8); //HH:mm
//时段2
String statTime2 = time.substring(8, 10) + ":" + time.substring(10, 12);
String closeTime2 = time.substring(12, 14) + ":" + time.substring(14, 16);
if (param.equals("L1")) {
deviceCodeParam.setRegisterAddr("0009"); //寄存器地址,L3路,L1(0009),L2(000D)
controlData.setUseStartTime1(statTime1);
controlData.setUseCloseTime1(closeTime1);
controlData.setUseStartTime2(statTime2);
controlData.setUseCloseTime2(closeTime2);
} else if (param.equals("L2")) {
deviceCodeParam.setRegisterAddr("000D");
controlData.setUseStartTime3(statTime1);
controlData.setUseCloseTime3(closeTime1);
controlData.setUseStartTime4(statTime2);
controlData.setUseCloseTime4(closeTime2);
} else {
deviceCodeParam.setRegisterAddr("0011");
controlData.setUseStartTime5(statTime1);
controlData.setUseCloseTime5(closeTime1);
controlData.setUseStartTime6(statTime2);
controlData.setUseCloseTime6(closeTime2);
}
deviceCodeParam.setDataValue(serialPortModel.getDataValue());
//controlData.setLevelSet(serialPortModel.getDataValue());
//controlSetService.saveControlSet(controlData);
nowDataService.upLevelSet(buildingId,serialPortModel.getDataValue());//更新实时状态表
}
serialPortSingle.serialPortSend(deviceCodeParam);//生成并发送指令
}else{
return HttpResult.error("通讯ID为空!");
controlSetService.saveControlSet(controlData); //保存设置内容
} else if (deviceType.equals("水位开关")) {
if (brand == null || brand.equals("") || brand.equals("中凯")) {//品牌
deviceCodeParam.setFunCode("12"); //功能码写数据
if (!serialPortModel.getDataValue().equals("100%")) {
deviceCodeParam.setDataValue("100%");
serialPortSingle.serialPortSend(deviceCodeParam);//生成并发送指令
Thread.sleep(1000);
}
} else if (brand.equals("远向")) {
deviceCodeParam.setFunCode("06"); //功能码写数据
if (!serialPortModel.getDataValue().equals("100%")) {
deviceCodeParam.setDataValue("100%");
serialPortSingle.serialPortSend(deviceCodeParam);//生成并发送指令
Thread.sleep(1000);
}
} else if (brand.equals("顶威")) {
deviceCodeParam.setFunCode("0407"); //功能码写数据
}
deviceCodeParam.setDataValue(serialPortModel.getDataValue());
//controlData.setLevelSet(serialPortModel.getDataValue());
//controlSetService.saveControlSet(controlData);
nowDataService.upLevelSet(buildingId, serialPortModel.getDataValue());//更新实时状态表
}
String returnStr = serialPortSingle.serialPortSend(deviceCodeParam);//生成并发送指令
if (!StringUtils.isBlank(returnStr) && "fail".equals(returnStr)) {
return HttpResult.error(500, "fail");
}
}
Constant.WEB_FLAG=false; //单抄,恢复采集
Constant.WEB_FLAG = false; //单抄,恢复采集
return HttpResult.ok();
}catch(Exception e){
// e.printStackTrace();
Constant.WEB_FLAG=false; //单抄,恢复采集
return HttpResult.error(500,"fail");
} catch (Exception e) {
log.error("前端发送控制异常==>", e);
Constant.WEB_FLAG = false; //单抄,恢复采集
return HttpResult.error(500, "fail");
} finally {
Constant.WEB_FLAG = false;
}
}
//读数据
@SysLogger(title="控制管理",optDesc = "读设备数据")
@PostMapping(value="/read")
public HttpResult readData(@RequestBody List<SerialPortModel> params){
try{
SerialPortSingle serialPortSingle = new SerialPortSingle();
DeviceCodeParamEntity deviceCodeParam=new DeviceCodeParamEntity();
String rtData=""; //返回值
Constant.WEB_FLAG=true; //单抄,暂时停止采集
@SysLogger(title = "控制管理", optDesc = "读设备数据")
@PostMapping(value = "/read/old")
public HttpResult readData(@RequestBody List<SerialPortModel> params) {
try {
SerialPortSingle2 serialPortSingle = new SerialPortSingle2();
DeviceCodeParamEntity deviceCodeParam = new DeviceCodeParamEntity();
String rtData = ""; //返回值
Constant.WEB_FLAG = true; //单抄,暂时停止采集
for (SerialPortModel serialPortModel :
params) {
String deviceAddr=serialPortModel.getDeviceAddr();//设备通讯地址
String deviceType=serialPortModel.getDeviceType();//设备类型
String buildingId=serialPortModel.getBuildingId();//楼栋
String param=serialPortModel.getParam();//操作参数
if (deviceAddr==null || deviceAddr=="" ){
List<DeviceModel> list=deviceInstallService.selectDevices(buildingId,deviceType);
deviceAddr=list.get(0).getDeviceAddr();
String deviceAddr = serialPortModel.getDeviceAddr();//设备通讯地址
String deviceType = serialPortModel.getDeviceType();//设备类型
String buildingId = serialPortModel.getBuildingId();//楼栋
String param = serialPortModel.getParam();//操作参数
if (StringUtils.isBlank(deviceAddr)) {
List<DeviceModel> list = deviceInstallService.selectDevices(buildingId, deviceType);
deviceAddr = list.get(0).getDeviceAddr();
}
if(deviceAddr!=null && deviceAddr.length()>0){
DeviceInstallEntity deviceInstallEntity=deviceInstallService.selectDevice(deviceAddr,deviceType,buildingId);
//发送指令实体类
deviceCodeParam.setDeviceAddr(deviceAddr);
deviceCodeParam.setDeviceType(deviceType);
deviceCodeParam.setDataCom(deviceInstallEntity.getDataCom());
deviceCodeParam.setBaudrate(deviceInstallEntity.getBaudRate());
deviceCodeParam.setParity(deviceInstallEntity.getParity());
deviceCodeParam.setDataValue(serialPortModel.getDataValue());//传入相关参数值
deviceCodeParam.setBuildingId(buildingId);
String brand=deviceInstallEntity.getBrand();//品牌
deviceCodeParam.setBrand(brand);
//设置设备实体对象
ControlSetEntity controlData=new ControlSetEntity();
controlData.setBuildingId(deviceInstallEntity.getBuildingId());
if (deviceType==null || deviceType.equals("") || deviceType.equals("热泵")){
//设置热泵实体对象
PumpSetEntity pumpData=new PumpSetEntity();
pumpData.setBuildingId(deviceInstallEntity.getBuildingId());
pumpData.setPumpId(deviceAddr);
if (param==null || param.equals("") || param.equals("读温度设定")){
deviceCodeParam.setFunCode("03"); //功能码读数据
if (brand.equals("美的")){
deviceCodeParam.setRegisterAddr("0642"); //寄存器地址
}else{
deviceCodeParam.setRegisterAddr("0003"); //寄存器地址
}
rtData=serialPortSingle.serialPortSend(deviceCodeParam);//生成并发送指令
if (!rtData.equals("")){
pumpData.setTempSet(rtData);
pumpSetService.savePumpSet(pumpData);//热泵信息保存数据库
}
} else if (param.equals("实际温度")){
deviceCodeParam.setFunCode("03"); //功能码读数据
if (brand.equals("美的")){
deviceCodeParam.setRegisterAddr("0007"); //寄存器地址
}else{
deviceCodeParam.setRegisterAddr("0064"); //寄存器地址
}
rtData=serialPortSingle.serialPortSend(deviceCodeParam);//生成并发送指令
if (!rtData.equals("")){
pumpData.setWaterTemp(rtData);
pumpSetService.savePumpSet(pumpData);//热泵信息保存数据库
}
} else if (param.equals("运行状态")){
deviceCodeParam.setFunCode("03"); //功能码读数据
if (brand.equals("美的")){
deviceCodeParam.setRegisterAddr("0641"); //寄存器地址
}else{
deviceCodeParam.setRegisterAddr("0BBD"); //寄存器地址
}
rtData=serialPortSingle.serialPortSend(deviceCodeParam);//生成并发送指令
//pumpData(rtData);
//pumpSetService.savePumpSet(pumpData);//热泵信息保存数据库
} else if(param.equals("时段1")){
if (brand.equals("美的")) {
//发送指令
deviceCodeParam.setRegisterAddr("0656"); //寄存器地址
deviceCodeParam.setFunCode("03"); //功能码读数据
//保存数据
rtData=serialPortSingle.serialPortSend(deviceCodeParam);//生成并发送指令
String time=rtData;
if (time.length()==8){
String statTime=time.substring(0,2)+":"+time.substring(2,4);
String closeTime=time.substring(4,6)+":"+time.substring(6,8);
if (StringUtils.isBlank(deviceAddr)) {
Constant.WEB_FLAG = false;
return HttpResult.error("通讯ID为空!");
}
DeviceInstallEntity deviceInstallEntity = deviceInstallService.selectDevice(deviceAddr, deviceType, buildingId);
//发送指令实体类
deviceCodeParam.setDeviceAddr(deviceAddr);
deviceCodeParam.setDeviceType(deviceType);
deviceCodeParam.setDataCom(deviceInstallEntity.getDataCom());
deviceCodeParam.setBaudrate(deviceInstallEntity.getBaudRate());
deviceCodeParam.setParity(deviceInstallEntity.getParity());
deviceCodeParam.setDataValue(serialPortModel.getDataValue());//传入相关参数值
deviceCodeParam.setBuildingId(buildingId);
String brand = deviceInstallEntity.getBrand();//品牌
deviceCodeParam.setBrand(brand);
//设置设备实体对象
ControlSetEntity controlData = new ControlSetEntity();
controlData.setBuildingId(deviceInstallEntity.getBuildingId());
if (StringUtils.isBlank(deviceType) || deviceType.equals("热泵")) {
//设置热泵实体对象
PumpSetEntity pumpData = new PumpSetEntity();
pumpData.setBuildingId(deviceInstallEntity.getBuildingId());
pumpData.setPumpId(deviceAddr);
if (StringUtils.isBlank(param) || param.equals("读温度设定")) {
deviceCodeParam.setFunCode("03"); //功能码读数据
if (brand.equals("美的")) {
deviceCodeParam.setRegisterAddr("0642"); //寄存器地址
} else {
deviceCodeParam.setRegisterAddr("0003"); //寄存器地址
}
rtData = serialPortSingle.serialPortSend(deviceCodeParam);//生成并发送指令
if (!rtData.equals("fail")) {
pumpData.setTempSet(rtData);
pumpSetService.savePumpSet(pumpData);//热泵信息保存数据库
}
} else if (param.equals("实际温度")) {
deviceCodeParam.setFunCode("03"); //功能码读数据
if (brand.equals("美的")) {
deviceCodeParam.setRegisterAddr("0007"); //寄存器地址
} else {
deviceCodeParam.setRegisterAddr("0064"); //寄存器地址
}
rtData = serialPortSingle.serialPortSend(deviceCodeParam);//生成并发送指令
if (!rtData.equals("fail")) {
pumpData.setWaterTemp(rtData);
pumpSetService.savePumpSet(pumpData);//热泵信息保存数据库
}
} else if (param.equals("运行状态")) {
deviceCodeParam.setFunCode("03"); //功能码读数据
if (brand.equals("美的")) {
deviceCodeParam.setRegisterAddr("0641"); //寄存器地址
} else {
deviceCodeParam.setRegisterAddr("0BBD"); //寄存器地址
}
rtData = serialPortSingle.serialPortSend(deviceCodeParam);//生成并发送指令
//pumpData(rtData);
//pumpSetService.savePumpSet(pumpData);//热泵信息保存数据库
} else if (param.equals("时段1")) {
if (brand.equals("美的")) {
//发送指令
deviceCodeParam.setRegisterAddr("0656"); //寄存器地址
deviceCodeParam.setFunCode("03"); //功能码读数据
//保存数据
rtData = serialPortSingle.serialPortSend(deviceCodeParam);//生成并发送指令
if (!rtData.equals("fail")) {
if (rtData.length() == 8) {
String statTime = rtData.substring(0, 2) + ":" + rtData.substring(2, 4);
String closeTime = rtData.substring(4, 6) + ":" + rtData.substring(6, 8);
pumpData.setStartTime1(statTime);
pumpData.setCloseTime1(closeTime);
}
pumpSetService.savePumpSet(pumpData);//热泵信息保存数据库
}
}else if(param.equals("时段2")){
if (brand.equals("美的")) {
//发送指令
deviceCodeParam.setRegisterAddr("065A"); //寄存器地址
deviceCodeParam.setFunCode("03"); //功能码读数据
//保存数据
rtData=serialPortSingle.serialPortSend(deviceCodeParam);//生成并发送指令
String time=rtData;
if (time.length()==8){
String statTime=time.substring(0,2)+":"+time.substring(2,4);
String closeTime=time.substring(4,6)+":"+time.substring(6,8);
}
} else if (param.equals("时段2")) {
if (brand.equals("美的")) {
//发送指令
deviceCodeParam.setRegisterAddr("065A"); //寄存器地址
deviceCodeParam.setFunCode("03"); //功能码读数据
//保存数据
rtData = serialPortSingle.serialPortSend(deviceCodeParam);//生成并发送指令
if (!rtData.equals("fail")) {
if (rtData.length() == 8) {
String statTime = rtData.substring(0, 2) + ":" + rtData.substring(2, 4);
String closeTime = rtData.substring(4, 6) + ":" + rtData.substring(6, 8);
pumpData.setStartTime2(statTime);
pumpData.setCloseTime2(closeTime);
}
pumpSetService.savePumpSet(pumpData);//热泵信息保存数据库
}
}
}else if (deviceType.equals("时控")){
if(param.equals("L1")){
deviceCodeParam.setRegisterAddr("0009"); //寄存器地址,L3路,L1(0009),L2(000D)
}else if(param.equals("L2")){
deviceCodeParam.setRegisterAddr("000D");
}else{
deviceCodeParam.setRegisterAddr("0011");
}
deviceCodeParam.setFunCode("03"); //功能码读数据
rtData=serialPortSingle.serialPortSend(deviceCodeParam);//生成并发送指令
String time=rtData;
if (time.length()==16){
}
} else if (deviceType.equals("时控")) {
if (param.equals("L1")) {
deviceCodeParam.setRegisterAddr("0009"); //寄存器地址,L3路,L1(0009),L2(000D)
} else if (param.equals("L2")) {
deviceCodeParam.setRegisterAddr("000D");
} else {
deviceCodeParam.setRegisterAddr("0011");
}
deviceCodeParam.setFunCode("03"); //功能码读数据
rtData = serialPortSingle.serialPortSend(deviceCodeParam);//生成并发送指令
if (!rtData.equals("fail")) {
if (rtData.length() == 16) {
//时段1
String statTime1=time.substring(0,2)+":"+time.substring(2,4);
String closeTime1=time.substring(4,6)+":"+time.substring(6,8);
String statTime1 = rtData.substring(0, 2) + ":" + rtData.substring(2, 4);
String closeTime1 = rtData.substring(4, 6) + ":" + rtData.substring(6, 8);
//时段2
String statTime2=time.substring(8,10)+":"+time.substring(10,12);
String closeTime2=time.substring(12,14)+":"+time.substring(14,16);
String statTime2 = rtData.substring(8, 10) + ":" + rtData.substring(10, 12);
String closeTime2 = rtData.substring(12, 14) + ":" + rtData.substring(14, 16);
if(param.equals("L1")){
if (param.equals("L1")) {
controlData.setUseStartTime1(statTime1);
controlData.setUseCloseTime1(closeTime1);
controlData.setUseStartTime2(statTime2);
controlData.setUseCloseTime2(closeTime2);
}else if(param.equals("L2")){
} else if (param.equals("L2")) {
controlData.setUseStartTime3(statTime1);
controlData.setUseCloseTime3(closeTime1);
controlData.setUseStartTime4(statTime2);
controlData.setUseCloseTime4(closeTime2);
}else{
} else {
controlData.setUseStartTime5(statTime1);
controlData.setUseCloseTime5(closeTime1);
controlData.setUseStartTime6(statTime2);
@ -340,83 +348,88 @@ public class SerialPortController {
}
}
controlSetService.saveControlSet(controlData); //保存设置内容
}else if (deviceType.equals("水位开关") && !param.equals("状态")){
if (brand==null || brand.equals("") || brand.equals("中凯")){//品牌
deviceCodeParam.setFunCode("17"); //功能码读
deviceCodeParam.setRegisterAddr("0017");
}else if(brand.equals("远向")){
deviceCodeParam.setFunCode("03"); //功能码读
deviceCodeParam.setRegisterAddr("0018");
}else if(brand.equals("顶威")){
deviceCodeParam.setFunCode("0102"); //功能码读
deviceCodeParam.setRegisterAddr("0102");
}
rtData=serialPortSingle.serialPortSend(deviceCodeParam);//生成并发送指令
deviceCodeParam.setDataValue(rtData);
//controlData.setLevelSet(serialPortModel.getDataValue());
//controlSetService.saveControlSet(controlData);
log.info("--------------读取返回数据:"+rtData+"------------------");
}else if (deviceType.equals("水位开关") && param.equals("状态")){
if(brand.equals("远向")){
deviceCodeParam.setFunCode("03"); //功能码读
deviceCodeParam.setRegisterAddr("0010");
}
rtData=serialPortSingle.serialPortSend(deviceCodeParam);//生成并发送指令
}else if (deviceType.equals("温度变送器")){
}
} else if (deviceType.equals("水位开关") && !param.equals("状态")) {
if (brand == null || brand.equals("") || brand.equals("中凯")) {//品牌
deviceCodeParam.setFunCode("17"); //功能码读
deviceCodeParam.setRegisterAddr("0017");
} else if (brand.equals("远向")) {
deviceCodeParam.setFunCode("03"); //功能码读
deviceCodeParam.setRegisterAddr("0028");
rtData=serialPortSingle.serialPortSend(deviceCodeParam);//生成并发送指令
}else if (deviceType.equals("压变")){
deviceCodeParam.setRegisterAddr("0018");
} else if (brand.equals("顶威")) {
deviceCodeParam.setFunCode("0102"); //功能码读
deviceCodeParam.setRegisterAddr("0102");
}
rtData = serialPortSingle.serialPortSend(deviceCodeParam);//生成并发送指令
//deviceCodeParam.setDataValue(rtData);
//controlData.setLevelSet(serialPortModel.getDataValue());
//controlSetService.saveControlSet(controlData);
log.info("--------------读取返回数据:" + rtData + "------------------");
} else if (deviceType.equals("水位开关") && param.equals("状态")) {
if (brand.equals("远向")) {
deviceCodeParam.setFunCode("03"); //功能码读
deviceCodeParam.setRegisterAddr("0004");
rtData=serialPortSingle.serialPortSend(deviceCodeParam);//生成并发送指令
}else if (deviceType.equals("水表")){
rtData=serialPortSingle.serialPortSend(deviceCodeParam);
}else if (deviceType.equals("电表")){
rtData=serialPortSingle.serialPortSend(deviceCodeParam);
deviceCodeParam.setRegisterAddr("0010");
}
rtData = serialPortSingle.serialPortSend(deviceCodeParam);//生成并发送指令
} else if (deviceType.equals("温度变送器")) {
deviceCodeParam.setFunCode("03"); //功能码读
deviceCodeParam.setRegisterAddr("0028");
rtData = serialPortSingle.serialPortSend(deviceCodeParam);//生成并发送指令
} else if (deviceType.equals("压变")) {
deviceCodeParam.setFunCode("03"); //功能码读
deviceCodeParam.setRegisterAddr("0004");
rtData = serialPortSingle.serialPortSend(deviceCodeParam);//生成并发送指令
} else if (deviceType.equals("水表")) {
rtData = serialPortSingle.serialPortSend(deviceCodeParam);
// 要添加校准值
Double deviationValue = deviceInstallService.selectDeviceDeviation(deviceCodeParam.getDeviceAddr(),deviceCodeParam.getDeviceType(), deviceCodeParam.getBuildingId());
if (null != deviationValue) {
rtData = new BigDecimal(rtData).add(BigDecimal.valueOf(deviationValue)).toString();
}
}else{
return HttpResult.error(500,"fail");
} else if (deviceType.equals("电表")) {
rtData = serialPortSingle.serialPortSend(deviceCodeParam);
}
}
Constant.WEB_FLAG=false; //单抄,恢复采集
if(ExchangeStringUtil.getJSONType(rtData)){
Map map = JSONObject.parseObject(rtData);
return HttpResult.ok("success",map);
}else{
if(rtData.equals("fail")){
return HttpResult.error(500,"fail");
}else{
return HttpResult.ok(rtData,rtData);
Constant.WEB_FLAG = false; //单抄,恢复采集
if (ExchangeStringUtil.getJSONType(rtData)) {
Map map = JSONObject.parseObject(rtData);
return HttpResult.ok("success", map);
} else {
if (rtData.equals("fail")) {
return HttpResult.error(500, "fail");
} else {
return HttpResult.ok(rtData, rtData);
}
}
}catch (Exception e){
Constant.WEB_FLAG=false; //单抄,恢复采集
return HttpResult.error(500,"fail");
} catch (Exception e) {
Constant.WEB_FLAG = false; //单抄,恢复采集
return HttpResult.error(500, "fail");
} finally {
Constant.WEB_FLAG = false; //单抄,恢复采集
}
}
@PostMapping(value="/pump")
public HttpResult queryPumpSet(@RequestParam(value = "pumpId",defaultValue = "2") String pumpId,
@RequestParam(value = "buildingId") String buildingId){
try{
PumpSetEntity list=pumpSetService.queryPumpSet(pumpId,buildingId);
@PostMapping(value = "/pump")
public HttpResult queryPumpSet(@RequestParam(value = "pumpId", defaultValue = "2") String pumpId,
@RequestParam(value = "buildingId") String buildingId) {
try {
PumpSetEntity list = pumpSetService.queryPumpSet(pumpId, buildingId);
return HttpResult.ok(list);
}catch (Exception e){
} catch (Exception e) {
//e.printStackTrace();
return HttpResult.error();
}
}
@PostMapping(value="/control")
public HttpResult queryControlSet(@RequestParam(value = "buildingId") String buildingId){
try{
ControlSetEntity list=controlSetService.queryControlSet(buildingId);
@PostMapping(value = "/control")
public HttpResult queryControlSet(@RequestParam(value = "buildingId") String buildingId, @RequestParam(value = "timeName", required = false) String timeName) {
try {
ControlSetEntity list = controlSetService.queryControlSet(buildingId, timeName);
return HttpResult.ok(list);
}catch (Exception e){
// e.printStackTrace();
} catch (Exception e) {
// e.printStackTrace();
return HttpResult.error();
}
}

85
user-service/src/main/java/com/mh/user/controller/TestController.java

@ -1,17 +1,16 @@
package com.mh.user.controller;
import com.mh.common.utils.DateTimeUtils;
import com.mh.user.constants.Constant;
import com.mh.user.dynamic.datasource.DataSourceContextHolder;
import com.mh.user.dynamic.datasource.DataSourceObject;
import com.mh.user.entity.DBEntity;
import com.mh.user.manage.QuartzManager;
import com.mh.user.mapper.NowDataMapper;
import com.mh.user.serialport.SerialTool;
import com.mh.user.service.NowDataService;
import com.mh.user.service.SysUserService;
import com.mh.user.utils.AESUtil;
import com.mh.user.utils.AnalysisReceiveOrder485;
import com.mh.user.utils.GetReadOrder485;
import com.mh.user.utils.TimedTask2;
import com.mh.user.utils.*;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
@ -19,6 +18,9 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import purejavacomm.CommPort;
import purejavacomm.CommPortIdentifier;
import purejavacomm.PortInUseException;
import javax.annotation.Resource;
@ -88,4 +90,79 @@ public class TestController {
}
@GetMapping
public String testCollection(String type) throws Exception {
purejavacomm.SerialPort serialPort1 = null;
System.out.println("开始时间==>" + DateTimeUtils.getDateTime());
String returnStr = "未采集到数据";
Constant.WEB_FLAG = true;
try {
if ("0".equals(type)) {
// 采集水表
// 采集水表
try {
serialPort1 = SerialTool.openPort("COM12",
2400,
purejavacomm.SerialPort.DATABITS_8,
purejavacomm.SerialPort.STOPBITS_1,
purejavacomm.SerialPort.PARITY_NONE);
} catch (PortInUseException e) {
System.out.println("进入异常==>");
if (null != serialPort1) {
serialPort1.close();
}
serialPort1 = SerialTool.openPort("COM12",
2400,
purejavacomm.SerialPort.DATABITS_8,
purejavacomm.SerialPort.STOPBITS_1,
purejavacomm.SerialPort.PARITY_NONE);
}
//从串口读取数据 SerialTool.sendToPort(SerialTool.HexString2Bytes(sendStr), serialPort, sendStr, deviceType);
String sendStr = "FE FE FE 68 10 39 87 10 81 00 00 00 01 03 90 1F 00 7C 16".replace(" ","");
SerialTool.sendToPort(SerialTool.HexString2Bytes(sendStr), serialPort1, sendStr, "水表");
Thread.sleep(888);
byte[] bytes = SerialTool.readFromPort(serialPort1);
assert bytes != null;
returnStr = ExchangeStringUtil.parseByte2HexStr(bytes);
System.out.println("控制读取回来的水表报文==>" + returnStr);
serialPort1.close();
}
if ("1".equals(type)) {
// 采集电表
// 采集电表
try {
serialPort1 = SerialTool.openPort("COM12",
1200,
purejavacomm.SerialPort.DATABITS_8,
purejavacomm.SerialPort.STOPBITS_1,
purejavacomm.SerialPort.PARITY_EVEN);
} catch (Exception e) {
System.out.println("进入异常==>");
if (null != serialPort1) {
serialPort1.close();
}
serialPort1 = SerialTool.openPort("COM12",
1200,
purejavacomm.SerialPort.DATABITS_8,
purejavacomm.SerialPort.STOPBITS_1,
purejavacomm.SerialPort.PARITY_EVEN);
}
//从串口读取数据 SerialTool.sendToPort(SerialTool.HexString2Bytes(sendStr), serialPort, sendStr, deviceType);
String sendStr = "FE FE FE 68 69 04 00 70 01 08 68 01 02 43 C3 BF 16".replace(" ","");
SerialTool.sendToPort(SerialTool.HexString2Bytes(sendStr), serialPort1, sendStr, "电表");
Thread.sleep(888);
byte[] bytes = SerialTool.readFromPort(serialPort1);
assert bytes != null;
returnStr = ExchangeStringUtil.parseByte2HexStr(bytes);
System.out.println("控制读取回来的电表报文==>" + returnStr);
serialPort1.close();
}
} finally {
Constant.WEB_FLAG = false;
}
System.out.println("结束时间==>" + DateTimeUtils.getDateTime());
return returnStr;
}
}

27
user-service/src/main/java/com/mh/user/dto/EnergyPreDTO.java

@ -0,0 +1,27 @@
package com.mh.user.dto;
import lombok.Getter;
import lombok.Setter;
/**
* @author LJF
* @version 1.0
* @project CHWS
* @description 用能预测前端类
* @date 2024-05-09 17:31:27
*/
@Setter
@Getter
public class EnergyPreDTO {
/**
* 顶部数据
*/
private EnergyPreTopDataDTO topData;
/**
* 折线图数据
*/
private EnergyPreEchartDataDTO echartData;
}

37
user-service/src/main/java/com/mh/user/dto/EnergyPreEchartDataDTO.java

@ -0,0 +1,37 @@
package com.mh.user.dto;
import lombok.Getter;
import lombok.Setter;
/**
* @author LJF
* @version 1.0
* @project CHWS
* @description 用能预测前端类
* @date 2024-05-09 17:31:27
*/
@Setter
@Getter
public class EnergyPreEchartDataDTO {
/**
* 时间
*/
private String curDate;
/**
* 实际值
*/
private String curData;
/**
* 预测值
*/
private String preData;
/**
* 误差值
*/
private String errorData;
}

37
user-service/src/main/java/com/mh/user/dto/EnergyPreTopDataDTO.java

@ -0,0 +1,37 @@
package com.mh.user.dto;
import lombok.Getter;
import lombok.Setter;
/**
* @author LJF
* @version 1.0
* @project CHWS
* @description 用能预测前端类
* @date 2024-05-09 17:31:27
*/
@Setter
@Getter
public class EnergyPreTopDataDTO {
/**
* 昨日实际值
*/
private String yesData;
/**
* 昨日预测值
*/
private String preYesData;
/**
* 今日预测值
*/
private String curYesData;
/**
* 误差值
*/
private String errorData;
}

2
user-service/src/main/java/com/mh/user/entity/BuildingEntity.java

@ -16,5 +16,7 @@ public class BuildingEntity {
private String areaId;
private String remarks;
private Double tankHeight;
private Double lowTankHeight;
private int pumpCount;
}

5
user-service/src/main/java/com/mh/user/entity/DeviceCodeParamEntity.java

@ -19,5 +19,10 @@ public class DeviceCodeParamEntity {
private String dataValue; //传入值
private Date createTime;
private String buildingId;
private String thread;
private Integer isuse;
private String param;
}

7
user-service/src/main/java/com/mh/user/entity/DeviceInstallEntity.java

@ -31,4 +31,11 @@ public class DeviceInstallEntity {
private Date installDate;
private String remarks;
private double dayValue;
private double deviationValue;
private int isUse;
private int isFault;
private String seat;
}

168
user-service/src/main/java/com/mh/user/entity/HistoryDataPre.java

@ -0,0 +1,168 @@
package com.mh.user.entity;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.math.BigDecimal;
import java.util.Date;
/**
* @author LJF
* @version 1.0
* @project CHWS
* @description 历史预测数据表
* @date 2024-05-09 09:55:09
*/
public class HistoryDataPre {
private Long id;
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date curDate;
private String buildingId;
private BigDecimal envMinTemp;
private BigDecimal envMaxTemp;
private BigDecimal waterValue;
private BigDecimal electValue;
private BigDecimal waterLevel;
/**
* 每栋楼人数
*/
private BigDecimal peopleNum;
private BigDecimal waterValuePre;
private BigDecimal electValuePre;
private BigDecimal waterLevelPre;
private String remark;
public BigDecimal getPeopleNum() {
return peopleNum;
}
public void setPeopleNum(BigDecimal peopleNum) {
this.peopleNum = peopleNum;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Date getCurDate() {
return curDate;
}
public void setCurDate(Date curDate) {
this.curDate = curDate;
}
public String getBuildingId() {
return buildingId;
}
public void setBuildingId(String buildingId) {
this.buildingId = buildingId;
}
public BigDecimal getEnvMinTemp() {
return envMinTemp;
}
public void setEnvMinTemp(BigDecimal envMinTemp) {
this.envMinTemp = envMinTemp;
}
public BigDecimal getEnvMaxTemp() {
return envMaxTemp;
}
public void setEnvMaxTemp(BigDecimal envMaxTemp) {
this.envMaxTemp = envMaxTemp;
}
public BigDecimal getWaterValue() {
return waterValue;
}
public void setWaterValue(BigDecimal waterValue) {
this.waterValue = waterValue;
}
public BigDecimal getElectValue() {
return electValue;
}
public void setElectValue(BigDecimal electValue) {
this.electValue = electValue;
}
public BigDecimal getWaterLevel() {
return waterLevel;
}
public void setWaterLevel(BigDecimal waterLevel) {
this.waterLevel = waterLevel;
}
public BigDecimal getWaterValuePre() {
return waterValuePre;
}
public void setWaterValuePre(BigDecimal waterValuePre) {
this.waterValuePre = waterValuePre;
}
public BigDecimal getElectValuePre() {
return electValuePre;
}
public void setElectValuePre(BigDecimal electValuePre) {
this.electValuePre = electValuePre;
}
public BigDecimal getWaterLevelPre() {
return waterLevelPre;
}
public void setWaterLevelPre(BigDecimal waterLevelPre) {
this.waterLevelPre = waterLevelPre;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
@Override
public String toString() {
return "HistoryDataPre{" +
"id=" + id +
", curDate=" + curDate +
", buildingId='" + buildingId + '\'' +
", envMinTemp=" + envMinTemp +
", envMaxTemp=" + envMaxTemp +
", waterValue=" + waterValue +
", electValue=" + electValue +
", waterLevel=" + waterLevel +
", waterValuePre=" + waterValuePre +
", electValuePre=" + electValuePre +
", waterLevelPre=" + waterLevelPre +
", remark='" + remark + '\'' +
'}';
}
}

38
user-service/src/main/java/com/mh/user/entity/KnowledgeDataEntity.java

@ -0,0 +1,38 @@
package com.mh.user.entity;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
import java.util.Date;
/**
* @author LJF
* @version 1.0
* @project CHWS
* @description 知识库管理
* @date 2024-06-26 14:18:28
*/
@Data
public class KnowledgeDataEntity implements Serializable {
private Long id;
@NotBlank(message = "标题不能为空")
private String title;
@NotBlank(message = "摘要不能为空")
private String description;
@NotBlank(message = "内容不能为空")
private String content;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createTime;
private Integer status;
private String remark;
}

1
user-service/src/main/java/com/mh/user/entity/MaintainInfoEntity.java

@ -18,6 +18,7 @@ public class MaintainInfoEntity {
private String maintainPeople; //维护人员
private Double cost; //费用
private String contents; //维保内容
private String evaluate; // 评价分数
}

1
user-service/src/main/java/com/mh/user/entity/SysParamEntity.java

@ -7,4 +7,5 @@ public class SysParamEntity {
private String customName; //公司或者单位名称
private String logo; //logo地址
private String proArea; // 区域编码
}

2
user-service/src/main/java/com/mh/user/entity/WaterLevelEntity.java

@ -10,11 +10,13 @@ public class WaterLevelEntity {
private Date curDate;
private String buildingID;
private String buildingName;
private String deviceName;
private String level00;
private String level02;
private String level08;
private String level11;
private String level13;
private String level14;
private String level15;
private String level16;
private String level17;

4
user-service/src/main/java/com/mh/user/entity/WaterTempEntity.java

@ -17,7 +17,7 @@ public class WaterTempEntity {
// private String temp03;
// private String temp04;
// private String temp05;
// private String temp06;
private String temp06;
// private String temp07;
private String temp08;
// private String temp09;
@ -25,7 +25,7 @@ public class WaterTempEntity {
private String temp11;
// private String temp12;
private String temp13;
// private String temp14;
private String temp14;
private String temp15;
private String temp16;
private String temp17;

20
user-service/src/main/java/com/mh/user/factory/Device.java

@ -0,0 +1,20 @@
package com.mh.user.factory;
import com.mh.user.entity.DeviceCodeParamEntity;
import com.mh.user.strategy.DeviceStrategy;
/**
* @author LJF
* @version 1.0
* @project CHWS
* @description 设备接口
* @date 2024-03-15 16:48:26
*/
public interface Device {
void setStrategy(DeviceStrategy strategy);
String createOrders(DeviceCodeParamEntity deviceCodeParamEntity);
String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String dataStr);
}

20
user-service/src/main/java/com/mh/user/factory/DeviceFactory.java

@ -0,0 +1,20 @@
package com.mh.user.factory;
import com.mh.user.constants.DeviceEnum;
import lombok.extern.slf4j.Slf4j;
/**
* @author LJF
* @version 1.0
* @project CHWS
* @description 设备工厂类
* @date 2024-03-15 17:09:49
*/
@Slf4j
public class DeviceFactory {
public static Device createDevice(String deviceType) {
return DeviceEnum.getDevice(deviceType);
}
}

46
user-service/src/main/java/com/mh/user/factory/EleMeter.java

@ -0,0 +1,46 @@
package com.mh.user.factory;
import com.mh.user.entity.DeviceCodeParamEntity;
import com.mh.user.strategy.DeviceStrategy;
import lombok.extern.slf4j.Slf4j;
/**
* @author LJF
* @version 1.0
* @project CHWS
* @description 电表设备
* @date 2024-03-15 16:52:39
*/
@Slf4j
public class EleMeter implements Device {
private DeviceStrategy eleMeterStrategy;
private static class SingletonHolder {
private static final EleMeter INSTANCE = new EleMeter();
}
private EleMeter() {
// 防止外部直接实例化
}
public static EleMeter getInstance() {
return EleMeter.SingletonHolder.INSTANCE;
}
@Override
public void setStrategy(DeviceStrategy strategy) {
this.eleMeterStrategy = strategy;
}
@Override
public String createOrders(DeviceCodeParamEntity deviceCodeParamEntity) {
log.info("电表设备创建报文");
return eleMeterStrategy.createOrders(deviceCodeParamEntity);
}
@Override
public String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String dataStr) {
return eleMeterStrategy.analysisReceiveData(dateStr, deviceType, registerAddr, brand, buildingId, buildingName, dataStr);
}
}

43
user-service/src/main/java/com/mh/user/factory/HeatPump.java

@ -0,0 +1,43 @@
package com.mh.user.factory;
import com.mh.user.entity.DeviceCodeParamEntity;
import com.mh.user.strategy.DeviceStrategy;
/**
* @author LJF
* @version 1.0
* @project CHWS
* @description 热泵
* @date 2024-03-18 16:53:35
*/
public class HeatPump implements Device {
private DeviceStrategy strategy;
private static class SingletonHolder {
private static final HeatPump INSTANCE = new HeatPump();
}
private HeatPump() {
// 防止外部直接实例化
}
public static HeatPump getInstance() {
return HeatPump.SingletonHolder.INSTANCE;
}
@Override
public void setStrategy(DeviceStrategy strategy) {
this.strategy = strategy;
}
@Override
public String createOrders(DeviceCodeParamEntity deviceCodeParamEntity) {
return strategy.createOrders(deviceCodeParamEntity);
}
@Override
public String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String dataStr) {
return strategy.analysisReceiveData(dateStr, deviceType, registerAddr, brand, buildingId, buildingName, dataStr);
}
}

43
user-service/src/main/java/com/mh/user/factory/HeatPumpStatus.java

@ -0,0 +1,43 @@
package com.mh.user.factory;
import com.mh.user.entity.DeviceCodeParamEntity;
import com.mh.user.strategy.DeviceStrategy;
/**
* @author LJF
* @version 1.0
* @project CHWS
* @description 热泵状态
* @date 2024-03-18 16:53:35
*/
public class HeatPumpStatus implements Device {
private DeviceStrategy strategy;
private static class SingletonHolder {
private static final HeatPumpStatus INSTANCE = new HeatPumpStatus();
}
private HeatPumpStatus() {
// 防止外部直接实例化
}
public static HeatPumpStatus getInstance() {
return HeatPumpStatus.SingletonHolder.INSTANCE;
}
@Override
public void setStrategy(DeviceStrategy strategy) {
this.strategy = strategy;
}
@Override
public String createOrders(DeviceCodeParamEntity deviceCodeParamEntity) {
return strategy.createOrders(deviceCodeParamEntity);
}
@Override
public String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String dataStr) {
return strategy.analysisReceiveData(dateStr, deviceType, registerAddr, brand, buildingId, buildingName, dataStr);
}
}

43
user-service/src/main/java/com/mh/user/factory/PressureTrans.java

@ -0,0 +1,43 @@
package com.mh.user.factory;
import com.mh.user.entity.DeviceCodeParamEntity;
import com.mh.user.strategy.DeviceStrategy;
/**
* @author LJF
* @version 1.0
* @project CHWS
* @description 压力变送器
* @date 2024-03-18 16:53:35
*/
public class PressureTrans implements Device {
private DeviceStrategy strategy;
private static class SingletonHolder {
private static final PressureTrans INSTANCE = new PressureTrans();
}
private PressureTrans() {
// 防止外部直接实例化
}
public static PressureTrans getInstance() {
return PressureTrans.SingletonHolder.INSTANCE;
}
@Override
public void setStrategy(DeviceStrategy strategy) {
this.strategy = strategy;
}
@Override
public String createOrders(DeviceCodeParamEntity deviceCodeParamEntity) {
return strategy.createOrders(deviceCodeParamEntity);
}
@Override
public String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String dataStr) {
return strategy.analysisReceiveData(dateStr, deviceType, registerAddr, brand, buildingId, buildingName, dataStr);
}
}

47
user-service/src/main/java/com/mh/user/factory/StatusCheck.java

@ -0,0 +1,47 @@
package com.mh.user.factory;
import com.mh.user.entity.DeviceCodeParamEntity;
import com.mh.user.strategy.DeviceStrategy;
import lombok.extern.slf4j.Slf4j;
/**
* @author LJF
* @version 1.0
* @project CHWS
* @description 状态检测
* @date 2024-03-15 17:07:54
*/
@Slf4j
public class StatusCheck implements Device {
private DeviceStrategy wtMeterStrategy;
private static class SingletonHolder {
private static final StatusCheck INSTANCE = new StatusCheck();
}
private StatusCheck() {
// 防止外部直接实例化
}
public static StatusCheck getInstance() {
return SingletonHolder.INSTANCE;
}
@Override
public void setStrategy(DeviceStrategy strategy) {
this.wtMeterStrategy = strategy;
}
@Override
public String createOrders(DeviceCodeParamEntity deviceCodeParamEntity) {
log.info("水表设备创建报文");
return wtMeterStrategy.createOrders(deviceCodeParamEntity);
}
@Override
public String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String dataStr) {
return wtMeterStrategy.analysisReceiveData(dateStr, deviceType, registerAddr, brand, buildingId, buildingName, dataStr);
}
}

43
user-service/src/main/java/com/mh/user/factory/TempControl.java

@ -0,0 +1,43 @@
package com.mh.user.factory;
import com.mh.user.entity.DeviceCodeParamEntity;
import com.mh.user.strategy.DeviceStrategy;
/**
* @author LJF
* @version 1.0
* @project CHWS
* @description 温度控制器
* @date 2024-03-18 16:53:35
*/
public class TempControl implements Device {
private DeviceStrategy strategy;
private static class SingletonHolder {
private static final TempControl INSTANCE = new TempControl();
}
private TempControl() {
// 防止外部直接实例化
}
public static TempControl getInstance() {
return TempControl.SingletonHolder.INSTANCE;
}
@Override
public void setStrategy(DeviceStrategy strategy) {
this.strategy = strategy;
}
@Override
public String createOrders(DeviceCodeParamEntity deviceCodeParamEntity) {
return strategy.createOrders(deviceCodeParamEntity);
}
@Override
public String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String dataStr) {
return strategy.analysisReceiveData(dateStr, deviceType, registerAddr, brand, buildingId, buildingName, dataStr);
}
}

43
user-service/src/main/java/com/mh/user/factory/TempTrans.java

@ -0,0 +1,43 @@
package com.mh.user.factory;
import com.mh.user.entity.DeviceCodeParamEntity;
import com.mh.user.strategy.DeviceStrategy;
/**
* @author LJF
* @version 1.0
* @project CHWS
* @description 压力变送器
* @date 2024-03-18 16:53:35
*/
public class TempTrans implements Device {
private DeviceStrategy strategy;
private static class SingletonHolder {
private static final TempTrans INSTANCE = new TempTrans();
}
private TempTrans() {
// 防止外部直接实例化
}
public static TempTrans getInstance() {
return TempTrans.SingletonHolder.INSTANCE;
}
@Override
public void setStrategy(DeviceStrategy strategy) {
this.strategy = strategy;
}
@Override
public String createOrders(DeviceCodeParamEntity deviceCodeParamEntity) {
return strategy.createOrders(deviceCodeParamEntity);
}
@Override
public String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String dataStr) {
return strategy.analysisReceiveData(dateStr, deviceType, registerAddr, brand, buildingId, buildingName, dataStr);
}
}

43
user-service/src/main/java/com/mh/user/factory/TimeControl.java

@ -0,0 +1,43 @@
package com.mh.user.factory;
import com.mh.user.entity.DeviceCodeParamEntity;
import com.mh.user.strategy.DeviceStrategy;
/**
* @author LJF
* @version 1.0
* @project CHWS
* @description 时间控制器
* @date 2024-03-18 16:53:35
*/
public class TimeControl implements Device {
private DeviceStrategy strategy;
private static class SingletonHolder {
private static final TimeControl INSTANCE = new TimeControl();
}
private TimeControl() {
// 防止外部直接实例化
}
public static TimeControl getInstance() {
return TimeControl.SingletonHolder.INSTANCE;
}
@Override
public void setStrategy(DeviceStrategy strategy) {
this.strategy = strategy;
}
@Override
public String createOrders(DeviceCodeParamEntity deviceCodeParamEntity) {
return strategy.createOrders(deviceCodeParamEntity);
}
@Override
public String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String dataStr) {
return strategy.analysisReceiveData(dateStr, deviceType, registerAddr, brand, buildingId, buildingName, dataStr);
}
}

43
user-service/src/main/java/com/mh/user/factory/WaterLevelSwitch.java

@ -0,0 +1,43 @@
package com.mh.user.factory;
import com.mh.user.entity.DeviceCodeParamEntity;
import com.mh.user.strategy.DeviceStrategy;
/**
* @author LJF
* @version 1.0
* @project CHWS
* @description 水位开关控制
* @date 2024-03-18 16:53:35
*/
public class WaterLevelSwitch implements Device {
private DeviceStrategy strategy;
private static class SingletonHolder {
private static final WaterLevelSwitch INSTANCE = new WaterLevelSwitch();
}
private WaterLevelSwitch() {
// 防止外部直接实例化
}
public static WaterLevelSwitch getInstance() {
return WaterLevelSwitch.SingletonHolder.INSTANCE;
}
@Override
public void setStrategy(DeviceStrategy strategy) {
this.strategy = strategy;
}
@Override
public String createOrders(DeviceCodeParamEntity deviceCodeParamEntity) {
return strategy.createOrders(deviceCodeParamEntity);
}
@Override
public String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String dataStr) {
return strategy.analysisReceiveData(dateStr, deviceType, registerAddr, brand, buildingId, buildingName, dataStr);
}
}

47
user-service/src/main/java/com/mh/user/factory/WtMeter.java

@ -0,0 +1,47 @@
package com.mh.user.factory;
import com.mh.user.entity.DeviceCodeParamEntity;
import com.mh.user.strategy.DeviceStrategy;
import lombok.extern.slf4j.Slf4j;
/**
* @author LJF
* @version 1.0
* @project CHWS
* @description 水表设备
* @date 2024-03-15 17:07:54
*/
@Slf4j
public class WtMeter implements Device {
private DeviceStrategy wtMeterStrategy;
private static class SingletonHolder {
private static final WtMeter INSTANCE = new WtMeter();
}
private WtMeter() {
// 防止外部直接实例化
}
public static WtMeter getInstance() {
return SingletonHolder.INSTANCE;
}
@Override
public void setStrategy(DeviceStrategy strategy) {
this.wtMeterStrategy = strategy;
}
@Override
public String createOrders(DeviceCodeParamEntity deviceCodeParamEntity) {
log.info("水表设备创建报文");
return wtMeterStrategy.createOrders(deviceCodeParamEntity);
}
@Override
public String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String dataStr) {
return wtMeterStrategy.analysisReceiveData(dateStr, deviceType, registerAddr, brand, buildingId, buildingName, dataStr);
}
}

87
user-service/src/main/java/com/mh/user/job/CollectionLoopRunner.java

@ -5,7 +5,11 @@ import com.mh.user.entity.AddCronJobReq;
import com.mh.user.manage.QuartzManager;
import com.mh.user.serialport.SerialPortListener;
import com.mh.user.serialport.SerialPortUtil;
import com.mh.user.utils.TimedTask2;
import com.mh.user.serialport.SerialTool;
import com.mh.user.service.DeviceCodeParamService;
import com.mh.user.utils.CacheUtil;
import com.mh.user.utils.ExchangeStringUtil;
import com.mh.user.utils.GetReadOrder485;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import org.springframework.boot.ApplicationArguments;
@ -31,10 +35,91 @@ public class CollectionLoopRunner implements ApplicationRunner {
public static SerialPort serialPort = null;
@Resource
private DeviceCodeParamService deviceCodeParamService;
@Resource
private GetWeatherInfoJob getWeatherInfoJob;
@Override
public void run(ApplicationArguments args) throws Exception {
// collectionMeterAndCloud();//采集
// Constant.WEB_FLAG=false; //恢复采集
// 初始化指令设备参数
initialDeviceCodeParams();
// 模拟采集
//simulationCollection();
// 获取天气数据
getWeatherInfoJob.getWeatherInfo();
}
private void simulationCollection() throws Exception {
purejavacomm.SerialPort serialPort1 = null;
do {
if (!Constant.WEB_FLAG) {
try {
// 采集水表
serialPort1 = SerialTool.openPort("COM12",
2400,
purejavacomm.SerialPort.DATABITS_8,
purejavacomm.SerialPort.STOPBITS_1,
purejavacomm.SerialPort.PARITY_NONE);
//从串口读取数据 SerialTool.sendToPort(SerialTool.HexString2Bytes(sendStr), serialPort, sendStr, deviceType);
// 81108739
String sendStr = "FE FE FE 68 10 39 87 10 81 00 00 00 01 03 90 1F 00 7C 16".replace(" ", "");
SerialTool.sendToPort(SerialTool.HexString2Bytes(sendStr), serialPort1, sendStr, "水表");
Thread.sleep(888);
byte[] bytes = SerialTool.readFromPort(serialPort1);
assert bytes != null;
String returnStr = ExchangeStringUtil.parseByte2HexStr(bytes);
System.out.println("响应报文==>" + returnStr);
serialPort1.close();
if (!Constant.WEB_FLAG) {
continue;
}
// 采集电表
serialPort1 = SerialTool.openPort("COM12",
1200,
purejavacomm.SerialPort.DATABITS_8,
purejavacomm.SerialPort.STOPBITS_1,
purejavacomm.SerialPort.PARITY_EVEN);
//从串口读取数据 SerialTool.sendToPort(SerialTool.HexString2Bytes(sendStr), serialPort, sendStr, deviceType);
// 080170000469
sendStr = "FE FE FE 68 69 04 00 70 01 08 68 01 02 43 C3 BF 16".replace(" ", "");
SerialTool.sendToPort(SerialTool.HexString2Bytes(sendStr), serialPort1, sendStr, "电表");
Thread.sleep(888);
bytes = SerialTool.readFromPort(serialPort1);
assert bytes != null;
returnStr = ExchangeStringUtil.parseByte2HexStr(bytes);
System.out.println("响应报文==>" + returnStr);
serialPort1.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != serialPort1) {
serialPort1.close();
}
}
}
} while (true);
}
private void initialDeviceCodeParams() {
GetReadOrder485 getReadOrder485 = new GetReadOrder485();
int r=deviceCodeParamService.queryCount(); //查询记录数
if (r==0){
getReadOrder485.createOrderParam(); //生成采集参数
}
int r1 = deviceCodeParamService.queryCount2(); //查询记录数
if (r1 == 0) {
getReadOrder485.createOrderParam2(); //生成采集参数
}
int r2=deviceCodeParamService.queryCount3();//查询记录数
if (r2==0){
getReadOrder485.createOrderParam3(); //生成采集参数
}
// 分组参数缓存
CacheUtil instance = CacheUtil.getInstance();
}
public void test() throws Exception {

194
user-service/src/main/java/com/mh/user/job/DealDataJob.java

@ -1,18 +1,26 @@
package com.mh.user.job;
import com.mh.user.constants.Constant;
import com.mh.user.serialport.SerialPortSendReceive;
import com.mh.user.entity.DeviceCodeParamEntity;
import com.mh.user.model.BuildingModel;
import com.mh.user.serialport.SerialPortThread;
import com.mh.user.service.DeviceCodeParamService;
import com.mh.user.service.BuildingService;
import com.mh.user.service.DealDataService;
import com.mh.user.utils.AnalysisReceiveOrder485;
import com.mh.user.utils.GetReadOrder485;
import com.mh.user.service.HistoryDataPreService;
import com.mh.user.utils.CacheUtil;
import com.mh.user.utils.ComThreadPoolService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;
/**
* @author ljf
@ -27,41 +35,41 @@ public class DealDataJob {
private final DealDataService dealDataService;
@Autowired
private DeviceCodeParamService deviceCodeParamService;
private GetReadOrder485 getReadOrder485;
private final BuildingService buildingService;
private static int taskTimes = 1;
private final HistoryDataPreService historyDataPreService;
public DealDataJob(DealDataService dealDataService)
{
public DealDataJob(DealDataService dealDataService, BuildingService buildingService, HistoryDataPreService historyDataPreService) {
this.dealDataService = dealDataService;
this.buildingService = buildingService;
this.historyDataPreService = historyDataPreService;
}
ThreadPoolExecutor comThreadPool = ComThreadPoolService.getInstance();
/**
* 定时处理汇总数据每15分钟处理一次,十分钟(0 0/10 * * * ?)
*/
@Scheduled(cron = "0 0/15 * * * ?")
public void ProEnergy() {
try {
SimpleDateFormat sdf1=new SimpleDateFormat("yyyy-MM-dd HH:00:00");
Date date=new Date();
String curDate=sdf1.format(date);
String name=dealDataService.customName();
if (name!=null && name.length()>0 && name.contains("华夏学院")){
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:00:00");
Date date = new Date();
String curDate = sdf1.format(date);
String name = dealDataService.customName();
if (name != null
&& (name.contains(Constant.CUSTOM_NAME_HUAXIA))) {
dealDataService.proEnergy2(curDate);
}else{
} else {
dealDataService.proEnergy(curDate); //yyyy-MM-dd HH:00:00
}
dealDataService.proGatewayState(); //判断网关在线状态:在线或离线
log.info("进入定时调试数据库过程汇总数据!yyyy-MM-dd HH:00:00");
} catch (Exception e) {
e.printStackTrace();
//Constant.FLAG=false;
//Constant.WEB_FLAG=false;
log.error("定时处理数据汇总异常==>", e);
}
}
/**
* 采集
*/
@ -70,84 +78,90 @@ public class DealDataJob {
// @Scheduled(cron = "0 0/5 * * * ?") //5分钟
public void collect() {
try {
log.info("------定时采集开始>>>>Constant.FLAG=="+Constant.FLAG+"------");
SerialPortSendReceive sendReceive=new SerialPortSendReceive();
if(Constant.FLAG==false){
if(Constant.WEB_FLAG==false){
log.info("------taskTimes=="+taskTimes+"------");
if (taskTimes<=4) {
Constant.FLAG=true;
log.info("------Constant.WEB_FLAG=="+Constant.WEB_FLAG+"------");
if (taskTimes == 2) {//2
int r = deviceCodeParamService.queryCount2(); //查询记录数
if (r == 0) {
getReadOrder485.createOrderParam2(); //生成采集参数
}
for(int i=1;i<11;i++){
SerialPortThread myThread = new SerialPortThread();
Thread thread = new Thread(myThread);
myThread.setName("2", String.valueOf(i));
thread.start();
}
log.info("------采集水、电、运行状态!"+taskTimes+"------");
}else if (taskTimes == 3){//3
for(int i=1;i<11;i++){
SerialPortThread myThread = new SerialPortThread();
Thread thread = new Thread(myThread);
myThread.setName("1", String.valueOf(i));
thread.start();
log.info("------定时采集开始>>>>Constant.FLAG==" + Constant.FLAG + "------");
if (!Constant.FLAG) {
if (!Constant.WEB_FLAG) {
Constant.FLAG = true;
log.info("------Constant.WEB_FLAG==" + false + "------");
CacheUtil cacheUtil = CacheUtil.getInstance();
for (int i = 1; i <= 4; i++) {
if (Constant.WEB_FLAG) {
break;
}
String threadName;
if (i == 1 || i == 3) {
threadName = "1";
log.info("------采集水位、水温!" + i + "------");
} else if (i == 2) {
threadName = "2";
log.info("------采集水、电、运行状态!" + i + "------");
} else {
threadName = "3";
log.info("------采集设定温度、设定水位、故障状态!" + i + "------");
}
// 从缓存中获取到对应的采集内容
List<DeviceCodeParamEntity> deviceParamsByType = cacheUtil.getDeviceParamsByType(threadName);
// 分组data_com
Map<String, List<DeviceCodeParamEntity>> dataComMap = deviceParamsByType.stream().collect(Collectors.groupingBy(DeviceCodeParamEntity::getDataCom));
int batchSize = 10; // 定义一个批次大小
int index = 0;
for (int k = 0; k < dataComMap.size(); ) {
if (Constant.WEB_FLAG) {
break;
}
log.info("------采集水位、水温!"+taskTimes+"------");
}else if (taskTimes == 4) {//4
for(int i=1;i<11;i++){
CountDownLatch countDownLatch = new CountDownLatch(Math.min(batchSize, dataComMap.size() - k));
index = k;
for (int j = 0; j < Math.min(batchSize, dataComMap.size() - k); j++) {
if (Constant.WEB_FLAG) {
break;
}
// 获取data_com口
String dataCom = dataComMap.keySet().toArray(new String[0])[index];
SerialPortThread myThread = new SerialPortThread();
myThread.setName(threadName, dataCom.toLowerCase().replace("com", ""), countDownLatch);
Thread thread = new Thread(myThread);
myThread.setName("3", String.valueOf(i));
thread.start();
comThreadPool.execute(thread);
index++;
}
log.info("------采集设定温度、设定水位、故障状态!"+taskTimes+"------");
}else {
for(int i=1;i<11;i++){
SerialPortThread myThread = new SerialPortThread();
Thread thread = new Thread(myThread);
myThread.setName("1", String.valueOf(i));
thread.start();
// 等待执行完成
countDownLatch.await();
// 释放资源
countDownLatch = null;
// 检查是否需要继续创建新的线程(未达到数据总数量且WEB_FLAG为false)
if (k + batchSize < dataComMap.size() && !Constant.WEB_FLAG) {
k += batchSize;
} else {
break;
}
log.info("------采集水位、水温!"+taskTimes+"------");
}
if(taskTimes<4){
taskTimes++;
}else{
taskTimes=1;
}
}
// Constant.FLAG=true;
// for(int i=1;i<4;i++){
// SerialPortThread myThread = new SerialPortThread();
// Thread thread = new Thread(myThread);
// myThread.setName("1",String.valueOf(i));
// thread.start();
// log.info("-------------采集水位、水温!线程"+String.valueOf(i)+"-------------");
// }
}
}
} catch (Exception e) {
e.printStackTrace();
log.error("定时采集异常==>", e);
} finally {
Constant.FLAG = false;
log.info("------定时采集结束>>>>Constant.FLAG==" + Constant.FLAG + "------");
}
}
/**
* 定时处理数据每十五分钟处理一次
*/
@Scheduled(cron = "0 0/15 * * * ?")
public void dealData() {
try {
SimpleDateFormat sdf1=new SimpleDateFormat("yyyy-MM-dd");
Date date=new Date();
String curDate=sdf1.format(date);
String name=dealDataService.customName();
if (name!=null && name.length()>0 && name.contains("华夏学院")){
StopWatch stopWatch = new StopWatch();
stopWatch.start();
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
Date date = new Date();
String curDate = sdf1.format(date);
String name = dealDataService.customName();
if (name != null
&& (name.contains(Constant.CUSTOM_NAME_HUAXIA))) {
dealDataService.proEnergySum2(curDate);
}else{
} else {
dealDataService.proEnergySum(curDate);
}
dealDataService.proMaintainSum(curDate); //汇总维修数
@ -158,10 +172,24 @@ public class DealDataJob {
dealDataService.proDeviceState(curDate); //汇总设备状态
dealDataService.proTotalPumpMinutes(curDate); //统计周\月热泵运行时长
log.info("进入定时调试数据库过程汇总数据!yyyy-MM-dd");
// // 开始预测数据
// List<BuildingModel> buildingModels = buildingService.selectBuildingName();
// for (BuildingModel buildingModel : buildingModels) {
// String buildingId = String.valueOf(buildingModel.getBuildingId());
// try {
// // 训练数据
// historyDataPreService.startTrainData(buildingId);
// // 预测数据
// historyDataPreService.startPredictData(buildingId, curDate);
// } catch (Exception e) {
// log.error("定时处理数据以及预测数据异常==>", e);
// }
// }
stopWatch.stop();
log.info("定时处理数据以及预测数据结束!耗时:" + stopWatch.getTotalTimeSeconds() + "秒");
} catch (Exception e) {
e.printStackTrace();
//Constant.FLAG=false;
//Constant.WEB_FLAG=false;
log.error("定时处理数据异常==>", e);
}
}

64
user-service/src/main/java/com/mh/user/job/GetWeatherInfoJob.java

@ -0,0 +1,64 @@
package com.mh.user.job;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.github.benmanes.caffeine.cache.Cache;
import com.mh.common.utils.StringUtils;
import com.mh.user.entity.SysParamEntity;
import com.mh.user.service.SysParamService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
/**
* @author LJF
* @version 1.0
* @project NewZhujiang_Server
* @description 定期获取时间
* @date 2023-12-05 14:12:56
*/
@Component
@Slf4j
public class GetWeatherInfoJob {
@Resource
private SysParamService sysParamService;
@Resource
private RestTemplate restTemplate;
@Resource
@Qualifier("caffeineCache")
private Cache caffeineCache;
@Value("${amap.key}")
String amapKey;
/**
* 定时获取每天天气
*/
@Scheduled(cron = "0 0 0 0/1 * ? ")
public void getWeatherInfo() {
// 从系统参数中获取对应的项目区域
SysParamEntity sysParam = sysParamService.selectSysParam();
if (null != sysParam) {
String url = "https://restapi.amap.com/v3/weather/weatherInfo?extensions=all&key="+amapKey+"&city="+sysParam.getProArea();
String returnResult = restTemplate.getForObject(url, String.class);
if (!StringUtils.isBlank(returnResult)) {
JSONObject jsonObject = JSON.parseObject(returnResult);
if ("1".equals(jsonObject.get("status"))) {
Object wetTemp = caffeineCache.getIfPresent(sysParam.getProArea());
if (wetTemp != null) {
caffeineCache.invalidate(sysParam.getProArea());
}
caffeineCache.put(sysParam.getProArea(), jsonObject.toString());
}
}
}
}
}

41
user-service/src/main/java/com/mh/user/job/JobCloud.java

@ -1,41 +0,0 @@
package com.mh.user.job;
import com.mh.user.netty.NettyClient;
import com.mh.user.constants.SocketMessage;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
/**
* @author ljf
* @title
* @description 定时采集冷量计任务
* @updateTime 2020-05-18
* @throws
*/
/**
* :@DisallowConcurrentExecution : 此标记用在实现Job的类上面,意思是不允许并发执行.
* :注意org.quartz.threadPool.threadCount线程池中线程的数量至少要多个,否则@DisallowConcurrentExecution不生效
* :假如Job的设置时间间隔为3秒,但Job执行时间是5秒,设置@DisallowConcurrentExecution以后程序会等任务执行完毕以后再去执行,
* 否则会在3秒时再启用新的线程执行
*/
@DisallowConcurrentExecution
@Slf4j
public class JobCloud implements Job {
@Autowired
private SocketMessage socketMessage;
@SneakyThrows
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
// 定时采集冷量计
log.info("定时采集冷量计");
NettyClient nettyClient = new NettyClient();
nettyClient.connect(socketMessage.getPort(),socketMessage.getIP());
}
}

39
user-service/src/main/java/com/mh/user/job/JobMeter.java

@ -1,39 +0,0 @@
package com.mh.user.job;
import com.mh.user.netty.NettyMeterClient;
import com.mh.user.constants.SocketMessage;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.springframework.beans.factory.annotation.Autowired;
/**
* @author ljf
* @title
* @description 定时采集电表数据任务
* @updateTime 2020-05-18
* @throws
*/
/**
* :@DisallowConcurrentExecution : 此标记用在实现Job的类上面,意思是不允许并发执行.
* :注意org.quartz.threadPool.threadCount线程池中线程的数量至少要多个,否则@DisallowConcurrentExecution不生效
* :假如Job的设置时间间隔为3秒,但Job执行时间是5秒,设置@DisallowConcurrentExecution以后程序会等任务执行完毕以后再去执行,
* 否则会在3秒时再启用新的线程执行
*/
@DisallowConcurrentExecution
@Slf4j
public class JobMeter implements Job {
@Autowired
private SocketMessage socketMessage;
@SneakyThrows
@Override
public void execute(JobExecutionContext jobExecutionContext) {
log.info("定时采集电表数据任务开始");
NettyMeterClient nettyMeterClient = new NettyMeterClient();
nettyMeterClient.connect(socketMessage.getPort(), socketMessage.getIP());
}
}

32
user-service/src/main/java/com/mh/user/job/JobTest.java

@ -1,32 +0,0 @@
package com.mh.user.job;
import com.mh.user.constants.Constant;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
/**
* :@DisallowConcurrentExecution : 此标记用在实现Job的类上面,意思是不允许并发执行.
* :注意org.quartz.threadPool.threadCount线程池中线程的数量至少要多个,否则@DisallowConcurrentExecution不生效
* :假如Job的设置时间间隔为3秒,但Job执行时间是5秒,设置@DisallowConcurrentExecution以后程序会等任务执行完毕以后再去执行,
* 否则会在3秒时再启用新的线程执行
*/
@DisallowConcurrentExecution
@Slf4j
public class JobTest implements Job {
@SneakyThrows
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
for (int i = 0; i < 30; i++) {
if (Constant.FLAG) {
break;
}
Thread.sleep(1000);
log.info("第" + i + "个," +jobExecutionContext.getJobDetail()+"---------------------定时任务测试----------------------");
}
}
}

32
user-service/src/main/java/com/mh/user/job/JobTest1.java

@ -1,32 +0,0 @@
package com.mh.user.job;
import com.mh.user.constants.Constant;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
/**
* :@DisallowConcurrentExecution : 此标记用在实现Job的类上面,意思是不允许并发执行.
* :注意org.quartz.threadPool.threadCount线程池中线程的数量至少要多个,否则@DisallowConcurrentExecution不生效
* :假如Job的设置时间间隔为3秒,但Job执行时间是5秒,设置@DisallowConcurrentExecution以后程序会等任务执行完毕以后再去执行,
* 否则会在3秒时再启用新的线程执行
*/
@DisallowConcurrentExecution
@Slf4j
public class JobTest1 implements Job {
@SneakyThrows
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
for (int i = 0; i < 30; i++) {
if (Constant.FLAG) {
break;
}
Thread.sleep(1000);
log.info("第" + i + "个," +jobExecutionContext.getJobDetail()+"---------------------定时任务测试----------------------");
}
}
}

190
user-service/src/main/java/com/mh/user/job/SendMeterWaterJob.java

@ -1,190 +0,0 @@
package com.mh.user.job;//package com.mh.quartz.job;
//
//import com.mh.quartz.manage.SerialPortManager;
//import com.mh.quartz.utils.AnalysisReceiveOrder485;
//import com.mh.quartz.utils.ExchangeStringUtil;
//import com.mh.quartz.utils.GetReadOrder485;
//import gnu.io.PortInUseException;
//import gnu.io.SerialPort;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.scheduling.annotation.Scheduled;
//import org.springframework.stereotype.Component;
//
//import java.util.Date;
//import java.util.concurrent.BlockingQueue;
//import java.util.concurrent.LinkedBlockingQueue;
//
///**
// * @author ljf
// * @title :
// * @description : 定时采集发送水电表数据
// * @updateTime 2020-04-22
// * @throws :
// */
//@Component
//@Slf4j
//public class SendMeterWaterJob {
//
// // 串口对象
// private SerialPort mSerialPort;
//
// AnalysisReceiveOrder485 analysisReceiveOrder485;
//
// // 测试
// @Scheduled(cron = "0,5 * * * * ? ")
// public void test() throws InterruptedException {
// Thread.sleep(10000);
// log.info("延迟10s");
// }
//
// @Scheduled(cron = "0,20,40 * * * * ? ")
// public void task1() throws PortInUseException, InterruptedException {
//
// // 堵塞队列用来存放读到的数据
// BlockingQueue<String> msgQueue = new LinkedBlockingQueue<String>();
// log.info("每0、20、40秒执行一次!");
// if (mSerialPort == null){
// // 打开串口
// } else {
// // 关闭串口
// SerialPortManager.closePort(mSerialPort);
// }
//
// mSerialPort = SerialPortManager.openPort("COM2",1200);
//
// // 发送数据(采集冷量计累计流量)
// String sendMeterOrderStr = "FEFEFE" + GetReadOrder485.createMeterOrder("080140001125","1");
// SerialPortManager.sendToPort(mSerialPort, ExchangeStringUtil.hexStrToBinaryStr(sendMeterOrderStr));
//
// // 添加串口监听
// SerialPort finalMSerialPort = mSerialPort;
// SerialPortManager.addListener(mSerialPort, () -> {
// byte[] data = null;
// try {
// // 读取串口数据
// data = SerialPortManager.readFromPort(finalMSerialPort);
// String needData = ExchangeStringUtil.printHexString(data);
// msgQueue.add(needData);
// } catch (Exception e) {
// log.info(e.getMessage());
// }
// });
//
// // 创建线程解析队列信息
// Thread thread = new Thread(() -> {
// try {
// log.info("--------------任务处理线程运行了--------------");
// String vo = "";
// String vos[] = new String[0];
// while (true) {
// // 判断数组是否完整
// // 电表
// if (vos.length >= 22) {
// log.info("获取到数据长度: " + vos.length);
// log.info("电表: " + new Date() + " 完整收到的数据为:-----" + vo);
// // 解析接收到的报文
// analysisReceiveOrder485.analysisMeterOrder485(vo);
// vos = new String[0];
// vo = "";
//// sendOrder();
// } else {
// // 如果堵塞队列中存在数据就将其输出
// if (msgQueue.size() > 0) {
// if (vo == "") {
// vo = msgQueue.peek();
// } else {
// vo = vo + " " + msgQueue.peek();
// }
// vos = vo.split(" ", -1);
//// getData(vos);
// msgQueue.take();
// }
// }
// }
// } catch (Exception e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// });
//
// thread.start();
//
// }
//
// @Scheduled(cron = "10,30,50 * * * * ? ")
// public void task2() throws PortInUseException, InterruptedException {
// // 堵塞队列用来存放读到的数据
// BlockingQueue<String> msgQueue = new LinkedBlockingQueue<String>();
// log.info("每10、30、50秒执行一次!");
// if (mSerialPort == null){
// // 打开串口
// } else {
// // 关闭串口
// SerialPortManager.closePort(mSerialPort);
// }
// mSerialPort = SerialPortManager.openPort("COM3",9600);
//
// // 发送数据(采集冷量计累计流量)
// String sendOrderStr = GetReadOrder485.createCloudOrder("88","34");
// SerialPortManager.sendToPort(mSerialPort, ExchangeStringUtil.hexStrToBinaryStr(sendOrderStr));
//
// // 添加串口监听
// SerialPort finalMSerialPort = mSerialPort;
// SerialPortManager.addListener(mSerialPort, () -> {
// byte[] data = null;
// try {
// // 读取串口数据
// data = SerialPortManager.readFromPort(finalMSerialPort);
// String needData = ExchangeStringUtil.printHexString(data);
// msgQueue.add(needData);
// } catch (Exception e) {
// log.info(e.getMessage());
// }
// });
//
// // 创建线程解析队列信息
// Thread thread = new Thread(() -> {
// try {
// log.info("--------------任务处理线程运行了--------------");
// String vo = "";
// String vos[] = new String[0];
// while (true) {
// // 判断数组是否完整
// // 冷量计
// if (vos.length >= 9) {
// if (vos.length == 9) {
// log.info("获取到数据长度: " + vos.length);
// log.info("冷量计: " + new Date() + " 完整收到的数据为:-----" + vo);
// // 解析接收到的报文
// analysisReceiveOrder485.analysisCloudOrder485(vo);
// }
// vos = new String[0];
// vo = "";
//// sendOrder();
// } else {
// // 如果堵塞队列中存在数据就将其输出
// if (msgQueue.size() > 0) {
// if (vo.equalsIgnoreCase("")){
// vo = msgQueue.peek();
// } else {
// vo = vo + " " + msgQueue.peek();
// }
// vos = vo.split(" ", -1);
//// getData(vos);
// msgQueue.take();
// }
// }
//
//
// }
// } catch (Exception e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// });
//
// thread.start();
//
// }
//
//}

7
user-service/src/main/java/com/mh/user/mapper/AnalysisMapper.java

@ -62,4 +62,11 @@ public interface AnalysisMapper {
@Select("select * from analysis_maintain_month where cur_date=#{curDate} and building_id=#{buildingId}")
List<AnalysisMonthEntity> queryAnalysisMaintainMonth(@Param("curDate") String curDate, @Param("buildingId") String buildingId);
@ResultMap("rs_day")
@Select("select * from analysis_runtime_month where cur_date=#{curDate} and building_id=#{buildingId}")
List<AnalysisMonthEntity> queryAnalysisRuntimeMonth(@Param("curDate") String curDate, @Param("buildingId") String buildingId);
@ResultMap("rs_month")
@Select("select * from analysis_runtime_year where cur_date=#{curDate} and building_id=#{buildingId}")
List<AnalysisYearEntity> queryAnalysisRuntimeYear(@Param("curDate") String curDate, @Param("buildingId") String buildingId);
}

16
user-service/src/main/java/com/mh/user/mapper/BuildingMapper.java

@ -15,8 +15,8 @@ public interface BuildingMapper {
* 保存楼栋信息
* @param buildingEntity
*/
@Insert("insert into building(building_name,levels_count,begin_level,house_count,bed_count,check_in_count,area_id,remarks,tankHeight) values (" +
"#{buildingName},#{levelsCount},#{beginLevel},#{houseCount},#{bedCount},#{checkInCount},#{areaId},#{remarks},#{tankHeight})")
@Insert("insert into building(building_name,levels_count,begin_level,house_count,bed_count,check_in_count,area_id,remarks,tankHeight,pump_count,low_tank_height) values (" +
"#{buildingName},#{levelsCount},#{beginLevel},#{houseCount},#{bedCount},#{checkInCount},#{areaId},#{remarks},#{tankHeight}, #{pumpCount}, #{lowTankHeight})")
int saveBuilding(BuildingEntity buildingEntity);
/**
@ -35,6 +35,8 @@ public interface BuildingMapper {
" <if test='areaId!=null'> , area_id = #{areaId} </if>" +
" <if test='remarks!=null'> , remarks = #{remarks} </if>" +
" <if test='tankHeight!=null'> , tankHeight = #{tankHeight} </if>" +
" <if test='lowTankHeight!=null'> , low_tank_height = #{lowTankHeight} </if>" +
" <if test='pumpCount!=null'> , pump_count = #{pumpCount} </if>" +
" where id = #{id} " +
"</script>")
int updateBuilding(BuildingEntity buildingEntity);
@ -55,7 +57,10 @@ public interface BuildingMapper {
@Result(property ="bedCount",column ="bed_count"),
@Result(property="checkInCount",column="check_in_count"),
@Result(property="areaId",column="area_id"),
@Result(property="remarks",column="remarks")
@Result(property="pumpCount",column="pump_count"),
@Result(property="remarks",column="remarks"),
@Result(property="tankHeight",column="tankHeight"),
@Result(property="lowTankHeight",column="low_tank_height")
})
@SelectProvider(type = BuildingProvider.class,method = "queryBuilding")
@ -112,4 +117,9 @@ public interface BuildingMapper {
@Select("select ISNULL(pump_count,0) from building where id=#{buildingId}")
int selectPumpCount(@Param("buildingId") String buildingId);
@Select("select building_name from building where id = #{buildingId} ")
String selectBuildingNameById(@Param("buildingId") String buildingId);
@Select("select low_tank_height from building where id=#{id}" )
Double queryLowTankHeight(@Param("id") String buildingId);
}

19
user-service/src/main/java/com/mh/user/mapper/ControlSetMapper.java

@ -60,6 +60,21 @@ public interface ControlSetMapper {
@Result(column = "back_water_temp", property = "backWaterTemp"),
@Result(column = "up_water_temp", property = "upWaterTemp"),
})
@Select("select * from control_Set where building_id=#{buildingId}")
ControlSetEntity queryControlSet(@Param("buildingId") String buildingId);
@Select("select " +
" top 1 " +
" * " +
"from " +
" control_Set " +
"where " +
" building_id = #{buildingId} " +
" and exists ( " +
" select " +
" 1 " +
" from " +
" device_install di " +
" where " +
" di.building_id = building_id " +
" and di.device_name like concat(#{timeName}, '时控') " +
") ")
ControlSetEntity queryControlSet(@Param("buildingId") String buildingId, @Param("timeName") String timeName);
}

2
user-service/src/main/java/com/mh/user/mapper/DealDataMapper.java

@ -68,7 +68,7 @@ public interface DealDataMapper {
void deleteDataHistory();
//查询学校名称
@Select("select customName from SysParam ")
@Select("select top 1 customName from SysParam ")
String customName();
//判断网关在线状态

54
user-service/src/main/java/com/mh/user/mapper/DeviceCodeParamMapper.java

@ -1,6 +1,7 @@
package com.mh.user.mapper;
import com.mh.user.entity.DeviceCodeParamEntity;
import com.mh.user.entity.DeviceInstallEntity;
import com.mh.user.entity.OrderMessageEntity;
import org.apache.ibatis.annotations.*;
@ -38,21 +39,39 @@ public interface DeviceCodeParamMapper {
//查询所有指令参数
@ResultMap("rs")
@Select("select * from device_code_param where thread=#{thread} order by data_com,device_type")
@Select("select * from device_code_param " +
// "<where>" +
// "<if test='thread != null and thread != \"\"'>" +
// " and thread=#{thread} " +
// "</if>" +
// "</where>" +
"order by data_com,device_type")
//@Select("select * from device_code_param order by data_com,device_type ")
// @Select("select * from device_code_param order by device_type ")
List<DeviceCodeParamEntity> queryCodeParam3(@Param("thread") String thread);
//查询所有指令参数
@ResultMap("rs")
@Select("select * from device_code_param2 where thread=#{thread} order by data_com,device_type")
@Select("select * from device_code_param2 " +
// "<where>" +
// "<if test='thread != null and thread != \"\"'>" +
// " and thread=#{thread} " +
// "</if>" +
// "</where>" +
"order by data_com,device_type")
//@Select("select * from device_code_param2 order by data_com,device_type ")
// @Select("select * from device_code_param2 order by device_type ")
List<DeviceCodeParamEntity> queryCodeParam4(@Param("thread") String thread);
//查询所有指令参数
@ResultMap("rs")
@Select("select * from device_code_param3 where thread=#{thread} order by data_com,device_type")
@Select("select * from device_code_param3 " +
// "<where>" +
// "<if test='thread != null and thread != \"\"'>" +
// " and thread=#{thread} " +
// "</if>" +
// "</where>" +
" order by data_com,device_type")
//@Select("select * from device_code_param3 order by data_com,device_type")
// @Select("select * from device_code_param3 order by device_type ")
List<DeviceCodeParamEntity> queryCodeParam5(@Param("thread") String thread);
@ -82,11 +101,12 @@ public interface DeviceCodeParamMapper {
"register_addr," +
"create_time," +
"building_id," +
"parity" +
"parity," +
"thread" +
")" +
"values " +
"<foreach collection='deviceCodeParamEntityList' item='item' separator=','>" +
"(#{item.deviceAddr},#{item.deviceName},#{item.deviceType},#{item.dataCom},#{item.baudrate},#{item.brand},#{item.funCode},#{item.registerAddr},getDate(),#{item.buildingId},#{item.parity})" +
"(#{item.deviceAddr},#{item.deviceName},#{item.deviceType},#{item.dataCom},#{item.baudrate},#{item.brand},#{item.funCode},#{item.registerAddr},getDate(),#{item.buildingId},#{item.parity},#{item.thread})" +
"</foreach>" +
"</script>")
void insertDeviceCodeParamList(@Param("deviceCodeParamEntityList") List<DeviceCodeParamEntity> deviceCodeParamEntityList);
@ -104,11 +124,12 @@ public interface DeviceCodeParamMapper {
"register_addr," +
"create_time," +
"building_id," +
"parity" +
"parity," +
"thread" +
")" +
"values " +
"<foreach collection='deviceCodeParamEntityList' item='item' separator=','>" +
"(#{item.deviceAddr},#{item.deviceName},#{item.deviceType},#{item.dataCom},#{item.baudrate},#{item.brand},#{item.funCode},#{item.registerAddr},getDate(),#{item.buildingId},#{item.parity})" +
"(#{item.deviceAddr},#{item.deviceName},#{item.deviceType},#{item.dataCom},#{item.baudrate},#{item.brand},#{item.funCode},#{item.registerAddr},getDate(),#{item.buildingId},#{item.parity},#{item.thread})" +
"</foreach>" +
"</script>")
void insertDeviceCodeParamList2(@Param("deviceCodeParamEntityList") List<DeviceCodeParamEntity> deviceCodeParamEntityList);
@ -126,17 +147,18 @@ public interface DeviceCodeParamMapper {
"register_addr," +
"create_time," +
"building_id," +
"parity" +
"parity," +
"thread" +
")" +
"values " +
"<foreach collection='deviceCodeParamEntityList' item='item' separator=','>" +
"(#{item.deviceAddr},#{item.deviceName},#{item.deviceType},#{item.dataCom},#{item.baudrate},#{item.brand},#{item.funCode},#{item.registerAddr},getDate(),#{item.buildingId},#{item.parity})" +
"(#{item.deviceAddr},#{item.deviceName},#{item.deviceType},#{item.dataCom},#{item.baudrate},#{item.brand},#{item.funCode},#{item.registerAddr},getDate(),#{item.buildingId},#{item.parity},#{item.thread})" +
"</foreach>" +
"</script>")
void insertDeviceCodeParamList3(@Param("deviceCodeParamEntityList") List<DeviceCodeParamEntity> deviceCodeParamEntityList);
//查询插入压变、温控
@Insert("insert into device_code_param(device_addr,device_name,device_type,data_com,baudrate,parity,brand,create_time,building_id) select device_addr,device_name,device_type,data_com,baudrate,parity,brand,getDate(),building_id from device_install where device_type='压变' or device_type='温控' or device_type='温度变送器' ")
@Insert("insert into device_code_param(device_addr,device_name,device_type,data_com,baudrate,parity,brand,create_time,building_id) select device_addr,device_name,device_type,data_com,baudrate,parity,brand,getDate(),building_id from device_install where device_type='压变' or device_type='温控' or device_type='温度变送器' ")
void selectInsertDeviceCodeParam();
//查询插入水、电表、状态检测
@ -146,4 +168,16 @@ public interface DeviceCodeParamMapper {
//查询插入水位开关
@Insert("insert into device_code_param3(device_addr,device_name,device_type,data_com,baudrate,parity,brand,create_time,building_id) select device_addr,device_name,device_type,data_com,baudrate,parity,brand,getDate(),building_id from device_install where device_type='水位开关' ")
void selectInsertDeviceCodeParam3();
@Delete("delete from device_code_param " +
" where device_addr=#{deviceAddr} and device_type = #{deviceType} and data_com = #{dataCom} and building_id = #{buildingId}")
void deleteParamCode1(DeviceInstallEntity oldEntity);
@Delete("delete from device_code_param2 " +
" where device_addr=#{deviceAddr} and device_type = #{deviceType} and data_com = #{dataCom} and building_id = #{buildingId}")
void deleteParamCode2(DeviceInstallEntity oldEntity);
@Delete("delete from device_code_param3 " +
" where device_addr=#{deviceAddr} and device_type = #{deviceType} and data_com = #{dataCom} and building_id = #{buildingId}")
void deleteParamCode3(DeviceInstallEntity oldEntity);
}

35
user-service/src/main/java/com/mh/user/mapper/DeviceInstallMapper.java

@ -1,25 +1,26 @@
package com.mh.user.mapper;
import com.mh.user.entity.BuildingEntity;
import com.mh.user.entity.DeviceInstallEntity;
import com.mh.user.entity.DeviceInstallTempEntity;
import com.mh.user.mapper.provider.DeviceInstallProvider;
import com.mh.user.model.DeviceModel;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.mapping.StatementType;
import tk.mybatis.mapper.common.BaseMapper;
import java.util.Date;
import java.util.List;
public interface
DeviceInstallMapper {
@Mapper
public interface DeviceInstallMapper extends BaseMapper<DeviceInstallEntity> {
/**
* 设备安装模块
* 保存设备信息
* @param deviceInstallEntity
*/
@Insert("insert into device_install(device_addr,device_name,device_type,data_com,ratio,baudrate,brand,model,building_id,installer,install_date,is_use) values (" +
" #{deviceAddr},#{deviceName},#{deviceType},#{dataCom},#{ratio},#{baudRate},#{brand},#{model},#{buildingId},#{installer},getDate(),#{use})")
@Insert("insert into device_install(device_addr,device_name,device_type,data_com,ratio,baudrate,brand,model,building_id,building_name,installer,install_date,is_use,parity) values (" +
" #{deviceAddr},#{deviceName},#{deviceType},#{dataCom},#{ratio},#{baudRate},#{brand},#{model},#{buildingId},#{buildingName},#{installer},getDate(),#{use},#{parity})")
int saveDevice(DeviceInstallEntity deviceInstallEntity);
/**
@ -42,6 +43,7 @@ DeviceInstallMapper {
" <if test='installer!=null'> , installer = #{installer} </if>" +
" <if test='buildingId!=null'> , building_id = #{buildingId} </if>" +
" <if test='remarks!=null'> , remarks = #{remarks} </if>" +
" <if test='parity!=null'> , parity = #{parity} </if>" +
" where id = #{id} " +
"</script>")
int updateDevice(DeviceInstallEntity deviceInstallEntity);
@ -158,7 +160,7 @@ DeviceInstallMapper {
//根据通讯地址和设备类型查询对应的设备信息
@ResultMap("rs")
@Select("select * from device_install where device_addr=#{deviceAddr} and device_type=#{deviceType} and building_id=#{buildingId}")
@Select("select top 1 * from device_install where device_addr=#{deviceAddr} and device_type=#{deviceType} and building_id=#{buildingId}")
DeviceInstallEntity selectDevice(@Param("deviceAddr") String deviceAddr,@Param("deviceType") String deviceType,@Param("buildingId") String buildingId);
//查询通讯编号是否存在
@ -309,4 +311,25 @@ DeviceInstallMapper {
//查询设备所属位置(低区或高区)
@Select("select seat from device_install where device_type=#{deviceType} and device_addr=#{deviceAddr} and building_id=#{buildingId} ")
String selectSeat(@Param("deviceType") String deviceType,@Param("deviceAddr") String deviceAddr,@Param("buildingId") String buildingId);
@Update("update device_install set deviation_value = #{realValue}-isnull(last_value,0) where device_type = #{deviceType} and building_id = #{buildingId}")
void updateDeviation(@Param("buildingId") Integer buildingId,
@Param("deviceType") String deviceType,
@Param("param") Integer param,
@Param("realValue") String realValue);
@Select("select isnull(deviation_value,0) from device_install where device_addr = #{deviceAddr} and device_type = #{deviceType} and building_id = #{buildingId}")
Double selectDeviceDeviation(@Param("deviceAddr") String deviceAddr,
@Param("deviceType") String deviceType,
@Param("buildingId") String buildingId);
@ResultMap("rs")
@Select("select * from device_install where id = #{id} ")
DeviceInstallEntity selectDeviceById(@Param("id") Long id);
@Update("update device_install set last_value = #{lastValue}, last_date = getdate() where device_addr = #{deviceAddr} and building_id = #{buildingId} and device_type = #{deviceType} ")
void updateLastValueByOther(@Param("deviceAddr") String addr,
@Param("lastValue") String strWtLevel,
@Param("deviceType") String deviceType,
@Param("buildingId") String buildingId);
}

227
user-service/src/main/java/com/mh/user/mapper/HistoryDataPreMapper.java

@ -0,0 +1,227 @@
package com.mh.user.mapper;
import com.mh.user.dto.EnergyPreEchartDataDTO;
import com.mh.user.dto.EnergyPreTopDataDTO;
import com.mh.user.entity.HistoryDataPre;
import org.apache.ibatis.annotations.*;
import org.springframework.security.core.parameters.P;
import tk.mybatis.mapper.common.BaseMapper;
import java.util.List;
/**
* @author LJF
* @version 1.0
* @project CHWS
* @description 预测历史数据mapper
* @date 2024-05-09 10:01:46
*/
@Mapper
public interface HistoryDataPreMapper extends BaseMapper<HistoryDataPre> {
@Results(id ="rs_train_data",value ={
@Result(column = "env_min_temp", property = "envMinTemp"),
@Result(column = "env_max_temp", property = "envMaxTemp"),
@Result(column = "water_value", property = "waterValue"),
@Result(column = "elect_value", property = "electValue"),
@Result(column = "water_level", property = "waterLevel"),
@Result(column = "people_num", property = "peopleNum")
})
@Select("select env_min_temp, env_max_temp, water_value, elect_value, water_level, people_num from history_data_pre where building_id = #{buildingId} order by cur_date ")
List<HistoryDataPre> getTrainData(@Param("buildingId") String buildingId);
@Results(id ="rs_recent_data",value ={
@Result(column = "id",property = "id" ),
@Result(column = "building_id", property = "buildingId"),
@Result(column = "cur_date", property = "curDate"),
@Result(column = "env_min_temp", property = "envMinTemp"),
@Result(column = "env_max_temp", property = "envMaxTemp"),
@Result(column = "water_value", property = "waterValue"),
@Result(column = "elect_value", property = "electValue"),
@Result(column = "water_level", property = "waterLevel"),
@Result(column = "water_value_pre", property = "waterValuePre"),
@Result(column = "elect_value_pre", property = "electValuePre"),
@Result(column = "water_level_pre", property = "waterLevelPre"),
@Result(column = "remark", property = "remark")
})
@Select("select * from history_date_pre where building_id = #{buildingId} and cur_date = #{curDate} order by cur_date ")
List<HistoryDataPre> getRecentData(@Param("buildingId") String buildingId,
@Param("curDate") String curDate);
@Update("update history_data_pre set water_value_pre = #{waterValuePre},elect_value_pre = #{electValuePre},water_level_pre = #{waterLevelPre}," +
" water_value = #{waterValue},elect_value = #{electValue},water_level = #{waterLevel} " +
" where id = #{id} and building_id = #{buildingId}")
void updateById(HistoryDataPre preHistoryData);
@Select("select count(*) from history_data_pre where building_id = #{buildingId} and cur_date = #{curDate} and env_min_temp is not null ")
int selectIsPre(@Param("buildingId") String buildingId,
@Param("curDate") String curDate);
@Results(id ="rs_cur_data",value ={
@Result(column = "id",property = "id" ),
@Result(column = "building_id", property = "buildingId"),
@Result(column = "cur_date", property = "curDate"),
@Result(column = "env_min_temp", property = "envMinTemp"),
@Result(column = "env_max_temp", property = "envMaxTemp"),
@Result(column = "water_value", property = "waterValue"),
@Result(column = "elect_value", property = "electValue"),
@Result(column = "water_level", property = "waterLevel")
})
@Select("select top 1 " +
" convert(date,eds.cur_date) as cur_date, " +
" eds.building_id, " +
" isnull(eds.water_value, " +
" 0) as water_value, " +
" isnull(eds.elect_value, " +
" 0) as elect_value, " +
" isnull(convert(numeric(24, " +
" 2), " +
" t1.water_level), " +
" 0) as water_level " +
"from " +
" energy_day_sum eds " +
"left join ( " +
" select " +
" convert(date, " +
" cur_date) as cur_date, " +
" building_id, " +
" avg(isnull(convert(numeric(24, 2), water_level), 0)) as water_level " +
" from " +
" history_data " +
" where " +
" building_id = #{buildingId} " +
" and cur_date = #{curDate} " +
" group by " +
" convert(date, " +
" cur_date), " +
" building_id " +
" ) t1 on " +
" eds.cur_date = t1.cur_date " +
" and eds.building_id = t1.building_id " +
"where " +
" eds.building_id != '所有' " +
" and eds.building_id = #{buildingId} " +
" and eds.cur_date = #{curDate} " +
"order by " +
" eds.building_id, " +
" eds.cur_date ")
HistoryDataPre selectCurData(@Param("buildingId") String buildingId,
@Param("curDate") String curDate);
@Insert("insert into history_data_pre(cur_date, building_id, env_min_temp, env_max_temp, water_value, elect_value, water_level) values(" +
"convert(date,#{curDate}), #{buildingId}, #{envMinTemp}, #{envMaxTemp}, #{waterValue}, #{electValue}, #{waterLevel}" +
")")
void insertData(HistoryDataPre curHistoryData);
@Results(id ="rs_one_data",value ={
@Result(column = "id",property = "id" ),
@Result(column = "building_id", property = "buildingId"),
@Result(column = "cur_date", property = "curDate"),
@Result(column = "env_min_temp", property = "envMinTemp"),
@Result(column = "env_max_temp", property = "envMaxTemp"),
@Result(column = "people_num", property = "peopleNum")
})
@Select("select top 1 id, building_id, cur_date, env_min_temp, env_max_temp, people_num from history_data_pre where building_id = #{buildingId} and cur_date = #{curDate} ")
HistoryDataPre selectOneData(@Param("buildingId") String buildingId,
@Param("curDate") String curDate);
@Results({
@Result(column = "cur_yes_data",property = "curYesData" ),
@Result(column = "yes_data", property = "yesData"),
@Result(column = "pre_yes_data", property = "preYesData"),
@Result(column = "error_data", property = "errorData")
})
@Select("<script>" +
"SELECT " +
" <choose>" +
" <when test='type == \"2\"'>" +
" isnull(t.water_value_pre, 0) as cur_yes_data, " +
" isnull(t1.water_value, 0) as yes_data, " +
" isnull(t1.water_value_pre, 0) as pre_yes_data, " +
" CASE WHEN t1.water_value_pre > 0 THEN CONVERT(decimal(18, 2), ABS(isnull(t1.water_value_pre, 0) - isnull(t1.water_value, 0)) / t1.water_value_pre * 100) ELSE '0' END as error_data" +
" </when>" +
" <when test='type == \"1\"'>" +
" isnull(t.elect_value_pre, 0) as cur_yes_data, " +
" isnull(t1.elect_value, 0) as yes_data, " +
" isnull(t1.elect_value_pre, 0) as pre_yes_data, " +
" CASE WHEN t1.elect_value_pre > 0 THEN CONVERT(decimal(18, 2), ABS(isnull(t1.elect_value_pre, 0) - isnull(t1.elect_value, 0)) / t1.elect_value_pre * 100) ELSE '0' END as error_data" +
" </when>" +
" <when test='type == \"3\"'>" +
" isnull(t.water_level_pre, 0) as cur_yes_data, " +
" isnull(t1.water_level, 0) as yes_data, " +
" isnull(t1.water_level_pre, 0) as pre_yes_data, " +
" CASE WHEN t1.water_level_pre > 0 THEN CONVERT(decimal(18, 2), ABS(isnull(t1.water_level_pre, 0) - isnull(t1.water_level, 0)) / t1.water_level_pre * 100) ELSE '0' END as error_data" +
" </when>" +
" <otherwise>null</otherwise>" +
" </choose>" +
"FROM (" +
" SELECT " +
" building_id, " +
" water_value, " +
" elect_value, " +
" water_level, " +
" water_value_pre, " +
" elect_value_pre, " +
" water_level_pre " +
" FROM history_data_pre " +
" WHERE cur_date = CONVERT(varchar(10), GETDATE(), 120) AND building_id = #{buildingId}" +
") t " +
"JOIN (" +
" SELECT " +
" building_id, " +
" water_value, " +
" elect_value, " +
" water_level, " +
" water_value_pre, " +
" elect_value_pre, " +
" water_level_pre " +
" FROM history_data_pre " +
" WHERE cur_date = CONVERT(varchar(10), DATEADD(day, -1, GETDATE()), 120) AND building_id = #{buildingId}" +
") t1 ON t.building_id = t1.building_id " +
"</script>")
List<EnergyPreTopDataDTO> getTopData(@Param("buildingId") String buildingId, @Param("type") String type);
@Results({
@Result(column = "cur_date",property = "curDate" ),
@Result(column = "cur_data", property = "curData"),
@Result(column = "pre_data", property = "preData"),
@Result(column = "error_data", property = "errorData")
})
@Select("<script>" +
"SELECT " +
" hdp.cur_date, " +
" <choose>" +
" <when test='type == \"2\"'>isnull(hdp.water_value, 0)</when>" +
" <when test='type == \"1\"'>isnull(hdp.elect_value, 0)</when>" +
" <when test='type == \"3\"'>isnull(hdp.water_level, 0)</when>" +
" <otherwise>0</otherwise>" +
" </choose> as cur_data, " +
" <choose>" +
" <when test='type == \"2\"'>isnull(hdp.water_value_pre, 0)</when>" +
" <when test='type == \"1\"'>isnull(hdp.elect_value_pre, 0)</when>" +
" <when test='type == \"3\"'>isnull(hdp.water_level_pre, 0)</when>" +
" <otherwise>0</otherwise>" +
" </choose> as pre_data, " +
" CASE " +
" <when test='type == \"2\"'>" +
" WHEN hdp.water_value_pre > 0 THEN CONVERT(decimal(18, 2), ABS(isnull(hdp.water_value_pre, 0) - isnull(hdp.water_value, 0)) / hdp.water_value_pre * 100) else 0 " +
" </when>" +
" <when test='type == \"1\"'>" +
" WHEN hdp.elect_value_pre > 0 THEN CONVERT(decimal(18, 2), ABS(isnull(hdp.elect_value_pre, 0) - isnull(hdp.elect_value, 0)) / hdp.elect_value_pre * 100) else 0 " +
" </when>" +
" <when test='type == \"3\"'>" +
" WHEN hdp.water_level_pre > 0 THEN CONVERT(decimal(18, 2), ABS(isnull(hdp.water_level_pre, 0) - isnull(hdp.water_level, 0)) / hdp.water_level_pre * 100) else 0 " +
" </when>" +
" END as error_data " +
"FROM history_data_pre hdp " +
"WHERE hdp.building_id = #{buildingId} " +
" AND cur_date BETWEEN #{beginDate} AND #{endDate} " +
"ORDER BY cur_date" +
"</script>")
List<EnergyPreEchartDataDTO> getEnergyPre(@Param("buildingId") String buildingId,
@Param("beginDate") String beginDate,
@Param("endDate") String endDate,
@Param("type") String type);
}

57
user-service/src/main/java/com/mh/user/mapper/KnowledgeDataMapper.java

@ -0,0 +1,57 @@
package com.mh.user.mapper;
import com.mh.user.entity.KnowledgeDataEntity;
import org.apache.ibatis.annotations.*;
import java.util.List;
/**
* @author LJF
* @version 1.0
* @project CHWS
* @description 知识库管理
* @date 2024-06-26 14:21:47
*/
@Mapper
public interface KnowledgeDataMapper {
@Insert("insert into knowledge_data(title,description,content,create_time,status,remark) " +
" values(#{title},#{description},#{content},getDate(),#{status},#{remark})")
void insertKnowledgeData(KnowledgeDataEntity knowledgeData);
@Results({
@Result(column = "id",property = "id" ),
@Result(column = "title", property = "title"),
@Result(column = "description", property = "description"),
@Result(column = "content", property = "content"),
@Result(column = "create_time", property = "createTime"),
@Result(column = "status", property = "status"),
@Result(column = "remark", property = "remark")
})
@Select("select id,title,description,content,create_time,status,remark from knowledge_data order by create_time desc")
List<KnowledgeDataEntity> findPage();
@Update("<script>" +
" update knowledge_data set " +
" <if test='title!=null'> title = #{title} </if>" +
" <if test='description!=null'> , description = #{description} </if>" +
" <if test='content!=null'> , content = #{content} </if>" +
" <if test='createTime!=null'> , create_time = #{createTime} </if>" +
" <if test='status!=null'> , status = #{status} </if>" +
" <if test='remark!=null'> , remark = #{remark} </if>" +
" where id = #{id} " +
"</script>")
void updateData(KnowledgeDataEntity knowledgeData);
@Results({
@Result(column = "id",property = "id" ),
@Result(column = "title", property = "title"),
@Result(column = "description", property = "description"),
@Result(column = "content", property = "content"),
@Result(column = "create_time", property = "createTime"),
@Result(column = "status", property = "status"),
@Result(column = "remark", property = "remark")
})
@Select("select id,title,description,content,create_time,status,remark from knowledge_data where id = #{id} order by create_time desc")
KnowledgeDataEntity getById(@Param("id") Long id);
}

8
user-service/src/main/java/com/mh/user/mapper/MaintainInfoMapper.java

@ -18,8 +18,8 @@ public interface MaintainInfoMapper {
* 维修保养信息
* @param maintainInfoEntity
*/
@Insert("insert into maintain_info(cur_date,building_id,device_type,device_addr,maintain_type,maintain_people,cost,contents) values (" +
" getDate(),#{buildingId},#{deviceType},#{deviceAddr},#{maintainType},#{maintainPeople},#{cost},#{contents})")
@Insert("insert into maintain_info(cur_date,building_id,device_type,device_addr,maintain_type,maintain_people,cost,contents, evaluate) values (" +
" getDate(),#{buildingId},#{deviceType},#{deviceAddr},#{maintainType},#{maintainPeople},#{cost},#{contents}, #{evaluate})")
int saveMaintainInfo(MaintainInfoEntity maintainInfoEntity);
/**
@ -36,6 +36,7 @@ public interface MaintainInfoMapper {
" <if test='maintainPeople!=null'> , maintain_people = #{maintainPeople} </if>" +
" <if test='cost!=null'> , cost = #{cost} </if>" +
" <if test='contents!=null'> , contents = #{contents} </if>" +
" <if test='evaluate!=null'> , evaluate = #{evaluate} </if>" +
" where id = #{id} " +
"</script>")
int updateMaintainInfo(MaintainInfoEntity maintainInfoEntity);
@ -61,7 +62,8 @@ public interface MaintainInfoMapper {
@Result(property="maintainPeople",column="maintain_people"),
@Result(property="id",column="id"),
@Result(property="cost",column="cost"),
@Result(property="contents",column="contents")
@Result(property="contents",column="contents"),
@Result(property="evaluate",column="evaluate")
})
List<MaintainInfoEntity> queryMaintainInfo(@Param("curDate") String curDate,
@Param("buildingId") String buildingId,

77
user-service/src/main/java/com/mh/user/mapper/NowDataMapper.java

@ -23,16 +23,16 @@ public interface NowDataMapper {
//修改监控界面实时信息(热泵)
@Update("<script>" +
" update now_data set cur_date=getDate()" +
" <if test='buildingName!=null'> , building_name = #{buildingName} </if>" +
" <if test='pumpName!=null'> , pump_name = #{pumpName} </if>" +
" <if test='tempSet!=null'> , temp_set = #{tempSet} </if>" +
" <if test='waterTemp!=null'> , water_temp = #{waterTemp} </if>" +
" <if test='runState!=null'> , run_state = #{runState} </if>" +
" <if test='isFault!=null'> , is_fault = #{isFault} </if>" +
" <if test='levelSet!=null'> , level_set = #{levelSet} </if>" +
" <if test='waterLevel!=null'> , water_level = #{waterLevel} </if>" +
" <if test='tankId!=null'> , tank_id = #{tankId} </if>" +
" <if test='tankName!=null'> , tank_name = #{tankName} </if>" +
" <if test='buildingName!=null and buildingName != \"\"'> , building_name = #{buildingName} </if>" +
" <if test='pumpName!=null and pumpName != \"\"'> , pump_name = #{pumpName} </if>" +
" <if test='tempSet!=null and tempSet != \"\"'> , temp_set = #{tempSet} </if>" +
" <if test='waterTemp!=null and waterTemp != \"\"'> , water_temp = #{waterTemp} </if>" +
" <if test='runState!=null and runState != \"\"'> , run_state = #{runState} </if>" +
" <if test='isFault!=null and isFault != \"\"'> , is_fault = #{isFault} </if>" +
" <if test='levelSet!=null and levelSet != \"\"'> , level_set = #{levelSet} </if>" +
" <if test='waterLevel!=null and waterLevel != \"\"'> , water_level = #{waterLevel} </if>" +
" <if test='tankId!=null and tankId != \"\"'> , tank_id = #{tankId} </if>" +
" <if test='tankName!=null and tankName != \"\"'> , tank_name = #{tankName} </if>" +
" where building_id = #{buildingId} and pump_id = #{pumpId} " +
"</script>")
void updateNowData(NowDataEntity nowDataEntity);
@ -40,17 +40,17 @@ public interface NowDataMapper {
//修改监控界面实时信息(不包含热泵)
@Update("<script>" +
" update now_data set cur_date=getDate()" +
" <if test='buildingName!=null'> , building_name = #{buildingName} </if>" +
" <if test='pumpId!=null'> , pump_id = #{pumpId} </if>" +
" <if test='pumpName!=null'> , pump_name = #{pumpName} </if>" +
" <if test='tempSet!=null'> , temp_set = #{tempSet} </if>" +
" <if test='waterTemp!=null'> , water_temp = #{waterTemp} </if>" +
" <if test='runState!=null'> , run_state = #{runState} </if>" +
" <if test='isFault!=null'> , is_fault = #{isFault} </if>" +
" <if test='levelSet!=null'> , level_set = #{levelSet} </if>" +
" <if test='waterLevel!=null'> , water_level = #{waterLevel} </if>" +
" <if test='tankId!=null'> , tank_id = #{tankId} </if>" +
" <if test='tankName!=null'> , tank_name = #{tankName} </if>" +
" <if test='buildingName!=null and buildingName != \"\"'> , building_name = #{buildingName} </if>" +
" <if test='pumpId!=null and pumpId != \"\"'> , pump_id = #{pumpId} </if>" +
" <if test='pumpName!=null and pumpName != \"\"'> , pump_name = #{pumpName} </if>" +
" <if test='tempSet!=null and tempSet != \"\"'> , temp_set = #{tempSet} </if>" +
" <if test='waterTemp!=null and waterTemp != \"\"'> , water_temp = #{waterTemp} </if>" +
" <if test='runState!=null and runState != \"\"'> , run_state = #{runState} </if>" +
" <if test='isFault!=null and isFault != \"\"'> , is_fault = #{isFault} </if>" +
" <if test='levelSet!=null and levelSet != \"\"'> , level_set = #{levelSet} </if>" +
" <if test='waterLevel!=null and waterLevel != \"\"'> , water_level = #{waterLevel} </if>" +
" <if test='tankId!=null and tankId != \"\"'> , tank_id = #{tankId} </if>" +
" <if test='tankName!=null and tankName != \"\"'> , tank_name = #{tankName} </if>" +
" where building_id = #{buildingId} " +
"</script>")
void updateNowData2(NowDataEntity nowDataEntity);
@ -176,7 +176,8 @@ public interface NowDataMapper {
@Results({
@Result(property="curDate",column="cur_date"),
@Result(property="buildingID",column="building_id"),
@Result(property="buildingName",column="building_name")
@Result(property="buildingName",column="building_name"),
@Result(property="deviceName",column="device_name")
})
@SelectProvider(type = NowDataProvider.class,method = "queryBuildWaterLevel")
List<WaterLevelEntity> queryBuildWaterLevel(@Param("curDate") String curDate,
@ -237,8 +238,13 @@ public interface NowDataMapper {
//初始化结束-----------------------------------------------------------------------------------------
//求热泵平均温度
@Select("select Convert(decimal(18,1),avg(CAST(water_temp as FLOAT))) from now_data where building_id=#{buildingId}")
String selectAve(@Param("buildingId") String buildingId);
@Select("<script>" +
"select Convert(decimal(18,1),avg(CAST(water_temp as FLOAT))) from now_data where building_id=#{buildingId} " +
"<if test='temp != null'>" +
" and water_temp >= #{temp} " +
"</if>" +
"</script>")
String selectAve(@Param("buildingId") String buildingId, @Param("temp") Integer temp);
//求单个热泵温度
@Select("select water_temp from now_data where pump_id=#{pumpId} and building_id=#{buildingId}")
@ -300,9 +306,9 @@ public interface NowDataMapper {
void proWaterTemp(@Param("curDate") String curDate,@Param("buildingID") String buildingID,@Param("pumpID") String pumpID);
//生成楼栋水位
@Select("exec pro_waterLevel #{curDate,jdbcType=VARCHAR,mode=IN},#{buildingID,jdbcType=VARCHAR,mode=IN} ")
@Select("exec pro_waterLevel #{curDate,jdbcType=VARCHAR,mode=IN},#{buildingID,jdbcType=VARCHAR,mode=IN}, #{deviceAddr,jdbcType=VARCHAR,mode=IN} ")
@Options(statementType = StatementType.CALLABLE)
void proWaterLevel(@Param("curDate") String curDate,@Param("buildingID") String buildingID);
void proWaterLevel(@Param("curDate") String curDate,@Param("buildingID") String buildingID, @Param("deviceAddr") String deviceAddr);
//在没有接收到返回值前设置监控界面热泵是否离线
@Update("update now_data set run_state=#{strState} where building_id=#{buildingId} and pump_id=#{pumpId}")
@ -389,20 +395,26 @@ public interface NowDataMapper {
//按高低区更新water_Level
@Update("update now_data SET now_data.water_Level=#{waterLevel} FROM device_install where now_data.pump_id =device_install.device_addr AND device_install.seat=#{seat} and now_data.building_id=#{buildingId} ")
@Update("update now_data SET now_data.water_Level=#{waterLevel} FROM device_install " +
" where now_data.pump_id =device_install.device_addr AND device_install.seat=#{seat} and now_data.building_id=#{buildingId} " +
" and now_data.building_id = device_install.building_id ")
void nowDataWaterLevel(@Param("waterLevel") String waterLevel,
@Param("seat") String seat,
@Param("buildingId") String buildingId);
//按高低区更新levelSet
@Update("update now_data SET now_data.level_set=#{levelSet} FROM device_install where now_data.pump_id =device_install.device_addr AND device_install.seat=#{seat} and now_data.building_id=#{buildingId} ")
@Update("update now_data SET now_data.level_set=#{levelSet} FROM device_install " +
" where now_data.pump_id =device_install.device_addr AND device_install.seat=#{seat} and now_data.building_id=#{buildingId} " +
" and now_data.building_id = device_install.building_id ")
void nowDataLevelSet(@Param("levelSet") String levelSet,
@Param("seat") String seat,
@Param("buildingId") String buildingId);
//按高低区更新water_Level
@Update("update history_Data SET history_Data.water_Level=#{waterLevel} FROM device_install where history_Data.pump_id =device_install.device_addr AND device_install.seat=#{seat} " +
" and history_Data.building_id=#{buildingId} and convert(varchar(13),cur_date,121)=left(#{curDate},13) ")
" and history_Data.building_id=#{buildingId} " +
" and convert(varchar(13),cur_date,121)=left(#{curDate},13)" +
" and history_Data.building_id = device_install.building_id ")
void historyDataWaterLevel(@Param("waterLevel") String waterLevel,
@Param("seat") String seat,
@Param("buildingId") String buildingId,
@ -410,9 +422,14 @@ public interface NowDataMapper {
//按高低区更新levelSet
@Update("update history_Data SET history_Data.level_set=#{levelSet} FROM device_install where history_Data.pump_id =device_install.device_addr AND device_install.seat=#{seat} " +
" and history_Data.building_id=#{buildingId} and convert(varchar(13),cur_date,121)=left(#{curDate},13) ")
" and history_Data.building_id=#{buildingId} " +
" and convert(varchar(13),cur_date,121)=left(#{curDate},13) " +
" and history_Data.building_id = device_install.building_id ")
void historyDataLevelSet(@Param("levelSet") String levelSet,
@Param("seat") String seat,
@Param("buildingId") String buildingId,
@Param("curDate") String curDate);
@Select("select count(1) from now_data where pump_name like '%热泵%' ")
int selectPumpCount(@Param("buildingId") String buildingId);
}

10
user-service/src/main/java/com/mh/user/mapper/NowPublicDataMapper.java

@ -87,7 +87,10 @@ public interface NowPublicDataMapper {
@Result(property ="singleTemp",column ="single_temp"),
@Result(property ="avgTemp",column ="use_water_temp")
})
@Select("select building_id,building_name,use_water_temp,single_temp from now_public_data")
@Select("select building_id,building_name," +
" convert(numeric(23,2),use_water_temp)+3 as use_water_temp, " +
" convert(numeric(23,2),single_temp)+3 as single_temp" +
" from now_public_data order by building_id ")
List<TempModel> queryWtTemp();
//查询单个楼栋水箱平均温度
@ -97,7 +100,10 @@ public interface NowPublicDataMapper {
@Result(property ="singleTemp",column ="single_temp"),
@Result(property ="avgTemp",column ="use_water_temp")
})
@Select("select building_id,building_name,use_water_temp,single_temp from now_public_data where building_id=#{buildingId} ")
@Select("select building_id,building_name," +
" convert(numeric(23,2),use_water_temp)+3 as use_water_temp, " +
" convert(numeric(23,2),single_temp)+3 as single_temp" +
" from now_public_data where building_id=#{buildingId} ")
TempModel queryWtTemp2(@Param("buildingId") String buildingId);
//更新单箱温度

20
user-service/src/main/java/com/mh/user/mapper/SysParamMapper.java

@ -0,0 +1,20 @@
package com.mh.user.mapper;
import com.mh.user.entity.SysParamEntity;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
/**
* @author LJF
* @version 1.0
* @project CHWS
* @description 系统参数
* @date 2024-01-16 08:58:43
*/
@Mapper
public interface SysParamMapper {
@Select("select top 1 * from SysParam ")
SysParamEntity selectSysParam();
}

12
user-service/src/main/java/com/mh/user/mapper/provider/NowDataProvider.java

@ -173,8 +173,12 @@ public class NowDataProvider {
StringBuffer sql = new StringBuffer("");
sql.append("select top 1000 * from (select *,ROW_NUMBER() over(order by cur_date) as rn from (" +
"select top 1000 t1.cur_date,t1.building_id,t2.building_name,t2.sort,convert(decimal(8,1),AVG(convert(float,t1.temp00)))as temp00," +
"convert(decimal(8,1),AVG(convert(float,t1.temp02)))as temp02," +
"convert(decimal(8,1),AVG(convert(float,t1.temp06)))as temp06," +
"convert(decimal(8,1),AVG(convert(float,t1.temp08)))as temp08,convert(decimal(8,1),AVG(convert(float,t1.temp11)))as temp11," +
"convert(decimal(8,1),AVG(convert(float,t1.temp13)))as temp13,convert(decimal(8,1),AVG(convert(float,t1.temp15)))as temp15," +
"convert(decimal(8,1),AVG(convert(float,t1.temp13)))as temp13," +
"convert(decimal(8,1),AVG(convert(float,t1.temp14)))as temp14," +
"convert(decimal(8,1),AVG(convert(float,t1.temp15)))as temp15," +
"convert(decimal(8,1),AVG(convert(float,t1.temp16)))as temp16,convert(decimal(8,1),AVG(convert(float,t1.temp17)))as temp17," +
"convert(decimal(8,1),AVG(convert(float,t1.temp18)))as temp18,convert(decimal(8,1),AVG(convert(float,t1.temp19)))as temp19," +
"convert(decimal(8,1),AVG(convert(float,t1.temp20)))as temp20,convert(decimal(8,1),AVG(convert(float,t1.temp21)))as temp21," +
@ -188,7 +192,6 @@ public class NowDataProvider {
} else if (page == 0){
sql.append(" )T )TT order by TT.cur_date desc ");
}
// System.out.println(sql.toString());
return sql.toString();
}
@ -197,8 +200,11 @@ public class NowDataProvider {
StringBuffer sql = new StringBuffer("");
sql.append("select count(*) from (select *,ROW_NUMBER() over(order by cur_date) as rn from (" +
"select t1.cur_date,t1.building_id,t2.building_name,t2.sort,convert(decimal(8,1),AVG(convert(float,t1.temp00)))as temp00," +
"convert(decimal(8,1),AVG(convert(float,t1.temp02)))as temp02,convert(decimal(8,1),AVG(convert(float,t1.temp06)))as temp06," +
"convert(decimal(8,1),AVG(convert(float,t1.temp08)))as temp08,convert(decimal(8,1),AVG(convert(float,t1.temp11)))as temp11," +
"convert(decimal(8,1),AVG(convert(float,t1.temp13)))as temp13,convert(decimal(8,1),AVG(convert(float,t1.temp15)))as temp15," +
"convert(decimal(8,1),AVG(convert(float,t1.temp13)))as temp13," +
"convert(decimal(8,1),AVG(convert(float,t1.temp14)))as temp14," +
"convert(decimal(8,1),AVG(convert(float,t1.temp15)))as temp15," +
"convert(decimal(8,1),AVG(convert(float,t1.temp16)))as temp16,convert(decimal(8,1),AVG(convert(float,t1.temp17)))as temp17," +
"convert(decimal(8,1),AVG(convert(float,t1.temp18)))as temp18,convert(decimal(8,1),AVG(convert(float,t1.temp19)))as temp19," +
"convert(decimal(8,1),AVG(convert(float,t1.temp20)))as temp20,convert(decimal(8,1),AVG(convert(float,t1.temp21)))as temp21," +

2
user-service/src/main/java/com/mh/user/mapper/provider/SysLogProvider.java

@ -5,7 +5,7 @@ public class SysLogProvider {
public String findLogs(String userName, int page, int limit){
StringBuffer sql = new StringBuffer("");
sql.append("select * from (" +
" select *,ROW_NUMBER() over(order by id) as rn from sys_log " +
" select *,ROW_NUMBER() over(order by create_time desc) as rn from sys_log " +
" where 1=1 ");
if (userName != null && !userName.equals("")){
sql.append(" AND user_name = #{userName} ");

20
user-service/src/main/java/com/mh/user/model/SerialPortModel.java

@ -5,9 +5,29 @@ import lombok.Data;
@Data
public class SerialPortModel {
/**
* 楼栋id
*/
private String buildingId;
/**
* 设备地址
*/
private String deviceAddr;
/**
* 设备类型
*/
private String deviceType;
/**
* 操作类型
*/
private String param;
/**
* 操作值
*/
private String dataValue;
}

98
user-service/src/main/java/com/mh/user/netty/NettyChillerControlClient.java

@ -1,98 +0,0 @@
package com.mh.user.netty;
import com.mh.user.entity.OrderMessageEntity;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.timeout.IdleStateHandler;
import io.netty.handler.timeout.ReadTimeoutHandler;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* @author ljf
* @title
* @description 控制冷水机组和其他设备
* @updateTime 2020-05-28
* @throws
*/
@Setter
@Getter
@Slf4j
public class NettyChillerControlClient {
// private int port;
// private String host;
// private List<OrderMessageEntity> orderMessageEntityList;
// 构造函数传递值 继承Thread时需要
// public NettyChillerControlClient(int port, String host) {
// this.port = port;
// this.host = host;
// }
public void connect(int port, String host, List<OrderMessageEntity> orderMessageEntityList) throws InterruptedException {
// 配置客户端NIO线程组
EventLoopGroup group = new NioEventLoopGroup(1);
try {
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group).channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY, true)
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 3000)
.option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(1024*1024))
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) {
// 基于换行符号
// socketChannel.pipeline().addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE,4,4,-8,0));
// // 解码转String,注意调整自己的编码格式GBK、UTF-8
// socketChannel.pipeline().addLast(new StringDecoder(StandardCharsets.UTF_8));
// // 解码转String,注意调整自己的编码格式GBK、UTF-8
// socketChannel.pipeline().addLast(new StringEncoder(StandardCharsets.UTF_8));
// socketChannel.pipeline().addLast(new LengthFieldPrepender(4));
// 超过10秒钟没有数据读取自动断开连接
// socketChannel.pipeline().addLast(new ReadTimeoutHandler(30));
// 超过10秒没有返回触发心跳机制 update by ljf on 2021-01-30
socketChannel.pipeline().addLast(new IdleStateHandler(10,10,6, TimeUnit.SECONDS));
// 在管道中添加我们自己的接收数据实现方法
socketChannel.pipeline().addLast(new NettyChillerControlHandler(orderMessageEntityList));
// socketChannel.pipeline().addLast(new NettyMeterClientHandler());
}
});
// 发起异步连接操作
ChannelFuture channelFuture = bootstrap.connect(host, port).sync();
if (channelFuture.isSuccess()) {
log.info("connect server 成功---------");
} else {
log.info("连接失败!");
log.info("准备重连!");
// connect(port, host);
}
// 等待客户端连接链路关闭future.channel().closeFuture().sync(); // 阻塞main线程
channelFuture.channel().closeFuture().sync();
} catch (Exception e) {
log.error(e.getMessage());
} finally {
group.shutdownGracefully();
// try {
// TimeUnit.SECONDS.sleep(5);
// connect(port, host); // 断线重连
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
}
}
// @SneakyThrows
// @Override
// public void run() {
// connect(port, host);
// }
}

311
user-service/src/main/java/com/mh/user/netty/NettyChillerControlHandler.java

@ -1,311 +0,0 @@
package com.mh.user.netty;
import com.mh.user.entity.OrderMessageEntity;
import com.mh.user.service.impl.DeviceDisplayServiceImpl;
import com.mh.user.constants.Constant;
import com.mh.user.utils.ExchangeStringUtil;
import com.mh.user.utils.SpringBeanUtil;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.ReferenceCountUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
/**
* @author ljf
* @title
* @description 客户端异步消息处理机制
* @updateTime 2020-05-13
* @throws
*/
@Slf4j
public class NettyChillerControlHandler extends ChannelHandlerAdapter {
private int num = 0;
private int size = 0;
private String receiveStr = "";
private int sendNum = 0;
private int idle_count = 1;
List<OrderMessageEntity> orderMessageEntityList;
// 调用service
ApplicationContext context = SpringBeanUtil.getApplicationContext();
DeviceDisplayServiceImpl.GatewayManageService gatewayManageService = context.getBean(DeviceDisplayServiceImpl.GatewayManageService.class);
//OrderMessageService orderMessageService = context.getBean(OrderMessageService.class);
public NettyChillerControlHandler(List<OrderMessageEntity> orderMessageEntityList) {
this.orderMessageEntityList = orderMessageEntityList;
}
@Override
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
log.info("当前channel从EventLoop取消注册");
// Constant.SEND_STATUS = false;
// super.channelUnregistered(ctx);
ctx.close();
}
/**
* 超时处理
* 如果120秒没有接受客户端的心跳就触发;
* 如果超过3次则直接关闭;
*/
@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())) { //如果读通道处于空闲状态,说明没有接收到心跳命令
System.out.println("第" + idle_count + "已经10秒没有接收到服务器的信息了,发送第" + num + "条数据");
if (num > size - 1) {
num = 0;
// 关闭连接
receiveStr = null;
Constant.SEND_STATUS = true;
System.out.println("关闭这个不活跃的channel");
ctx.close();
} else if (idle_count > 3) {
System.out.println("关闭这个不活跃的channel");
num = 0;
// 关闭连接
receiveStr = null;
Constant.SEND_STATUS = false;
ctx.close();
} else {
// 发送采集DDC指令
// 判断空值
if (orderMessageEntityList.get(num).getRegisterAddr() == null ||
orderMessageEntityList.get(num).getRegisterAddr().equalsIgnoreCase("")) {
num = 0;
// 关闭连接
receiveStr = null;
Constant.SEND_STATUS = true;
ctx.close();
} else {
String sendStr = orderMessageEntityList.get(num).getOrderStr();
// // 获取采集参数个数
// size = orderMessageEntityList.size();
// 2.发送数据
ByteBuf buffer = getByteBuf(ctx, sendStr);
ctx.channel().writeAndFlush(buffer);
idle_count++;
}
}
}
} else {
super.userEventTriggered(ctx, obj);
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
// super.exceptionCaught(ctx, cause);
log.info("通信异常!!");
cause.printStackTrace();
// receiveStr = null;
// Channel incoming = ctx.channel();
// if (incoming.isActive()) {
// // 重新发送
// if (sendNum > 2) {
// // 通信异常,发送失败
// log.info("SimpleClient: " + incoming.remoteAddress() + "异常");
// cause.printStackTrace();
// Constant.SEND_STATUS = false;
// ctx.close();
// } else {
// // 发送采集DDC指令
// String sendStr = orderMessageEntityList.get(num).getOrderStr();
// // 获取采集参数个数
// size = orderMessageEntityList.size();
// // 2.发送数据
// ByteBuf buffer = getByteBuf(ctx,sendStr);
// ctx.channel().writeAndFlush(buffer);
// sendNum += 1;
// }
// }
// // 判断发送的下标,如果不等于指令数组大小
// num = num + 1;
// if (num > size-1) {
// num = 0;
// // 关闭连接
// receiveStr = null;
// Constant.SEND_STATUS = true;
// ctx.close();
// }
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
SimpleDateFormat sdf1=new SimpleDateFormat("yyyy-mm-dd HH:mm:ss");
Date date=new Date();
log.info(ctx.channel().remoteAddress() + " " + sdf1.format(date) + "链接服务端成功!");
// 截取IP地址
String IP = ExchangeStringUtil.getMidString(ctx.channel().remoteAddress()+"","/", ":");
// 截取端口号
String port = ExchangeStringUtil.getMidString(ctx.channel().remoteAddress()+"",":", "");
log.info("IP: " + IP + ",端口号: " + port);
// 更新对应的网关在线情况
gatewayManageService.updateGatewayManage(IP, port);
// 发送控制DDC指令
String sendStr = orderMessageEntityList.get(num).getOrderStr();
// 获取采集参数个数
size = orderMessageEntityList.size();
// 2.发送数据
ByteBuf buffer = getByteBuf(ctx,sendStr);
ctx.channel().writeAndFlush(buffer);
}
private ByteBuf getByteBuf(ChannelHandlerContext ctx, String sendStr) {
// 申请一个数据结构存储信息
ByteBuf buffer = ctx.alloc().buffer();
// 将信息放入数据结构中
buffer.writeBytes(ExchangeStringUtil.hexStrToBinaryStr(sendStr));//对接需要16进制
return buffer;
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
// Thread.sleep(100);
ctx.close();
log.info(ctx.channel().localAddress() + "退出链接!!");
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
// super.channelRead(ctx, msg);
// ByteBuf buf = (ByteBuf)msg;
// byte[] req = new byte[buf.readableBytes()];
// buf.readBytes(req);
// String body = new String(req, "UTF-8");
try {
ByteBuf buf = (ByteBuf)msg;
byte [] bytes = new byte[buf.readableBytes()];
buf.readBytes(bytes);//复制内容到字节数组bytes
buf.clear();
log.info("获取到的值: " + ExchangeStringUtil.bytesToHexString(bytes));
// if (bytes.length <= 24) {
if (bytes.length != 0) {
// receiveStr = receiveStr.replace("null", "");
// receiveStr = receiveStr + ExchangeStringUtil.bytesToHexString(bytes);//将接收到的数据转为字符串,此字符串就是客户端发送的字符串
// log.info(ctx.channel().remoteAddress() + " " + ctx.channel().localAddress() + " 接受服务器数据:" + receiveStr + ",大小: " + receiveStr.length());
receiveStr = receiveStr + ExchangeStringUtil.bytesToHexString(bytes);//将接收到的数据转为字符串,此字符串就是客户端发送的字符串
receiveStr = receiveStr.replace("null", "");
log.info("接受服务器数据:" + receiveStr + ",大小: " + receiveStr.length());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
ReferenceCountUtil.release(msg);
}
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
log.info("数据读取接收完成: " + receiveStr);
if (receiveStr.length() == 24) {
if (receiveStr.equalsIgnoreCase(orderMessageEntityList.get(num).getOrderStr())) {
// 解析采集回来的数据
log.info("采集完整的报文: " + receiveStr + ",指令下标: " + size);
// 解析采集的报文
// 更新发送后的指令
OrderMessageEntity orderMessageEntity = new OrderMessageEntity();
orderMessageEntity.setRegisterAddr(orderMessageEntityList.get(num).getRegisterAddr());
orderMessageEntity.setCreateTime(orderMessageEntityList.get(num).getCreateTime());
orderMessageEntity.setGrade(1);
orderMessageEntity.setSendNum(1);
orderMessageEntity.setStatus(1);
orderMessageEntity.setOrderStr(orderMessageEntityList.get(num).getOrderStr());
//orderMessageService.updateOrderMessage(orderMessageEntity);
// // 关闭连接
// receiveStr = null;
// Constant.SEND_STATUS = true;
// ctx.close();
// 清空receiveStr
receiveStr = "";
// 判断发送的下标,如果不等于指令数组大小
num = num + 1;
if (num > size - 1) {
num = 0;
// 关闭连接
receiveStr = null;
Constant.SEND_STATUS = true;
ctx.close();
} else {
Thread.sleep(4000);
// 继续发送下一个采集DDC设备指令
String sendStr = orderMessageEntityList.get(num).getOrderStr();
ByteBuf buffer = getByteBuf(ctx, sendStr);
// 2.发送数据
ctx.channel().writeAndFlush(buffer);
log.info("客户端再次往服务端发送数据" + num + ",报文: " + sendStr);
}
}
} else if ((receiveStr.length() > 24) && (num == 0)) {
// 发送采集DDC指令
String sendStr = orderMessageEntityList.get(num).getOrderStr();
// 获取采集参数个数
size = orderMessageEntityList.size();
// 2.发送数据
ByteBuf buffer = getByteBuf(ctx,sendStr);
ctx.channel().writeAndFlush(buffer);
// 清空receiveStr
receiveStr = "";
sendNum += 1;
} else if (sendNum > 2){
// 更新发送后的指令
OrderMessageEntity orderMessageEntity = new OrderMessageEntity();
orderMessageEntity.setRegisterAddr(orderMessageEntityList.get(num).getRegisterAddr());
orderMessageEntity.setCreateTime(orderMessageEntityList.get(num).getCreateTime());
orderMessageEntity.setGrade(1);
orderMessageEntity.setSendNum(sendNum);
orderMessageEntity.setStatus(0);
orderMessageEntity.setOrderStr(orderMessageEntityList.get(num).getOrderStr());
//orderMessageService.updateOrderMessage(orderMessageEntity);
Constant.SEND_STATUS = false;
ctx.close();
} else if ((receiveStr.length() > 24)) {
// 接收采集DDC的数据
// 解析采集的报文
// AnalysisReceiveOrder485 analysisReceiveOrder485 = new AnalysisReceiveOrder485();
// analysisReceiveOrder485.analysisChillersDDC(receiveStr);
// 清空receiveStr
receiveStr = "";
// 更新发送后的指令
OrderMessageEntity orderMessageEntity = new OrderMessageEntity();
orderMessageEntity.setRegisterAddr(orderMessageEntityList.get(num).getRegisterAddr());
orderMessageEntity.setCreateTime(orderMessageEntityList.get(num).getCreateTime());
orderMessageEntity.setGrade(1);
orderMessageEntity.setSendNum(1);
orderMessageEntity.setStatus(1);
orderMessageEntity.setOrderStr(orderMessageEntityList.get(num).getOrderStr());
//orderMessageService.updateOrderMessage(orderMessageEntity);
// 判断发送的下标,如果不等于指令数组大小
num = num + 1;
// Thread.sleep(500);
if (num > size-1) {
num = 0;
// 关闭连接
receiveStr = null;
Constant.SEND_STATUS = true;
ctx.close();
}
}
ctx.flush();
}
}

90
user-service/src/main/java/com/mh/user/netty/NettyClient.java

@ -1,90 +0,0 @@
package com.mh.user.netty;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.timeout.ReadTimeoutHandler;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
/**
* @author ljf
* @title
* @description Netty客户端采集冷量计
* @updateTime 2020-05-13
* @throws
*/
@Slf4j
@Setter
@Getter
public class NettyClient {
private int port;
private String host;
// 构造函数传递值 继承Thread时需要
// public NettyClient(int port, String host) {
// this.port = port;
// this.host = host;
// }
public void connect(int port, String host) throws InterruptedException {
// 配置客户端NIO线程组
EventLoopGroup group = new NioEventLoopGroup(1);
try {
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group).channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY, true)
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 3000)
.option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(1024*1024))
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) {
// 基于换行符号
// socketChannel.pipeline().addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE,4,4,-8,0));
// // 解码转String,注意调整自己的编码格式GBK、UTF-8
// socketChannel.pipeline().addLast(new StringDecoder(StandardCharsets.UTF_8));
// // 解码转String,注意调整自己的编码格式GBK、UTF-8
// socketChannel.pipeline().addLast(new StringEncoder(StandardCharsets.UTF_8));
// socketChannel.pipeline().addLast(new LengthFieldPrepender(4));
// 超过10秒钟没有数据读取自动断开连接
socketChannel.pipeline().addLast(new ReadTimeoutHandler(10));
// 在管道中添加我们自己的接收数据实现方法
socketChannel.pipeline().addLast(new NettyClientHandler());
// socketChannel.pipeline().addLast(new NettyMeterClientHandler());
}
});
// 发起异步连接操作
ChannelFuture channelFuture = bootstrap.connect(host, port).sync();
if (channelFuture.isSuccess()) {
log.info("connect server 成功---------");
} else {
log.info("连接失败!");
log.info("准备重连!");
// connect(port, host);
}
// 等待客户端连接链路关闭future.channel().closeFuture().sync(); // 阻塞main线程
channelFuture.channel().closeFuture().sync();
} catch (Exception e) {
log.error(e.getMessage());
} finally {
group.shutdownGracefully();
// try {
// TimeUnit.SECONDS.sleep(5);
// connect(port, host); // 断线重连
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
}
}
// @SneakyThrows
// @Override
// public void run() {
// connect(port, host);
// }
}

295
user-service/src/main/java/com/mh/user/netty/NettyClientHandler.java

@ -1,295 +0,0 @@
package com.mh.user.netty;
import com.mh.user.constants.Constant;
import com.mh.user.entity.DeviceManageEntity;
import com.mh.user.service.DeviceManageService;
import com.mh.user.utils.*;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.ReferenceCountUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
/**
* @author ljf
* @title
* @description 客户端异步消息处理机制
* @updateTime 2020-05-13
* @throws
*/
@Slf4j
public class NettyClientHandler extends ChannelHandlerAdapter {
private int num = 0;
private int size = 0;
private String receiveStr = null;
private String IP = null;
private String port = null;
List<DeviceManageEntity> deviceManageEntityList;
// 调用service
ApplicationContext context = SpringBeanUtil.getApplicationContext();
DeviceManageService deviceManageService = context.getBean(DeviceManageService.class);
@Override
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
log.info("当前channel从EventLoop取消注册");
super.channelUnregistered(ctx);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
// super.exceptionCaught(ctx, cause);
log.info("通信异常!!");
receiveStr = null;
Channel incoming = ctx.channel();
if (incoming.isActive()){
log.info("SimpleClient: " + incoming.remoteAddress() + "异常");
cause.printStackTrace();
ctx.close();
// receiveStr = null;
// try {
// TimeUnit.SECONDS.sleep(5);
// SocketAddress remoteAddress = ctx.channel().remoteAddress();
// String port = ExchangeStringUtil.endData(remoteAddress.toString(),":");
// String host = ExchangeStringUtil.splitData(remoteAddress.toString(),"/",":");
// NettyClient nettyClient = new NettyClient();
// nettyClient.connect(Integer.parseInt(port), host); // 断线重连
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
}
}
@Override
public void channelActive(ChannelHandlerContext ctx) {
// 添加一个状态值,判断是否继续发送指令 update by ljf on 2020-08-07
if (Constant.WEB_FLAG) {
num = 0;
// 关闭连接
receiveStr = null;
ctx.close();
} else {
ctx.channel().read();
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss");
Date date = new Date();
log.info(ctx.channel().remoteAddress() + " " + sdf1.format(date) + "链接服务端成功!");
// 截取IP地址
IP = ExchangeStringUtil.getMidString(ctx.channel().remoteAddress() + "", "/", ":");
// 截取端口号
port = ExchangeStringUtil.getMidString(ctx.channel().remoteAddress() + "", ":", "");
log.info("IP: " + IP + ",端口号: " + port);
// 生成对应采集冷量计的命令
// 生成对应的采集指令
deviceManageEntityList = deviceManageService.queryDevicesByType("3");
size = deviceManageEntityList.size();
// 封装工具类进行采集,update by ljf on 2021-01-26
SendOrderUtils.sendCloudOrder(deviceManageEntityList.get(0),0,IP,port,ctx);
// // 1.创建将要写出的数据
// String collectionNum = deviceManageEntityList.get(0).getCollectionNum();
// String sendStr = GetReadOrder485.createCloudOrder(IP, port,
// deviceManageEntityList.get(0).getDataCom(),
// collectionNum, "34");
//// String sendStr = "5803004900021914";
// ByteBuf buffer = getByteBuf(ctx, sendStr);
// // 2.发送数据
// ctx.channel().writeAndFlush(buffer);
}
// String sendStr = "5803004900021914"; // 冷量计
// // 申请一个数据结构存储信息
// ByteBuf buffer = ctx.alloc().buffer();
// // 将信息放入数据结构中
// buffer.writeBytes(ExchangeStringUtil.hexStrToBinaryStr(sendStr));//对接需要16进制
// ctx.writeAndFlush(buffer, ctx.newProgressivePromise());
}
private ByteBuf getByteBuf(ChannelHandlerContext ctx, String sendStr) {
// byte类型的数据
// byte[] bytes = "这里是将要写往服务端的数据".getBytes(Charset.forName("utf-8"));
// String sendStr = "5803004900021914"; // 冷量计
// 申请一个数据结构存储信息
ByteBuf buffer = ctx.alloc().buffer();
// 将信息放入数据结构中
buffer.writeBytes(ExchangeStringUtil.hexStrToBinaryStr(sendStr));//对接需要16进制
return buffer;
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
Thread.sleep(100);
ctx.close();
log.info(ctx.channel().localAddress() + "退出链接!!");
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
try {
ByteBuf buf = (ByteBuf)msg;
byte [] bytes = new byte[buf.readableBytes()];
buf.readBytes(bytes);//复制内容到字节数组bytes
buf.clear();
log.info("获取到的值: " + ExchangeStringUtil.bytesToHexString(bytes));
if (bytes.length <= 36) {
// receiveStr = receiveStr.replace("null", "");
// receiveStr = receiveStr + ExchangeStringUtil.bytesToHexString(bytes);//将接收到的数据转为字符串,此字符串就是客户端发送的字符串
// log.info(ctx.channel().remoteAddress() + " " + ctx.channel().localAddress() + " 接受服务器数据:" + receiveStr + ",大小: " + receiveStr.length());
receiveStr = receiveStr + ExchangeStringUtil.bytesToHexString(bytes);//将接收到的数据转为字符串,此字符串就是客户端发送的字符串
receiveStr = receiveStr.replace("null", "");
log.info("接受服务器数据:" + receiveStr + ",大小: " + receiveStr.length());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
ReferenceCountUtil.release(msg);
}
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
log.info("采集冷量计-数据读取接收完成: " + receiveStr);
// A9 FE C2 C7 1F 90 01 58 03 04 4A 30 00 53 65 1C C4 06
if (receiveStr.length() == 36) {
// 接收到的报文
log.info("接收完整报文: " + receiveStr);
// 解析报文
// AnalysisReceiveOrder485 analysisReceiveOrder485 = new AnalysisReceiveOrder485();
// analysisReceiveOrder485.analysisCloudOrder485(receiveStr); // 解析冷量计
receiveStr = "";
// 1.创建将要写出的数据
// String sendStr = "5803004900021914";
num = num + 1;
Thread.sleep(500);
if (num > size-1) {
num = 0;
// 关闭连接
receiveStr = null;
ctx.close();
// 保持长连接
// // 封装工具类进行采集,update by ljf on 2021-01-26
// SendOrderUtils.sendCloudOrder(deviceManageEntityList.get(num),num,IP,port,ctx);
} else {
// 添加一个状态值,判断是否继续发送指令 update by ljf on 2020-08-07
if (Constant.WEB_FLAG) {
log.info("有指令下发退出定时采集DDC参数");
num = 0;
// 关闭连接
receiveStr = null;
ctx.close();
} else {
// 封装工具类进行采集,update by ljf on 2021-01-26
SendOrderUtils.sendCloudOrder(deviceManageEntityList.get(num),num,IP,port,ctx);
// // 1.创建将要写出的数据
// String collectionNum = deviceManageEntityList.get(num).getCollectionNum();
// String sendStr = GetReadOrder485.createCloudOrder(IP, port,
// deviceManageEntityList.get(num).getDataCom(),
// collectionNum, "34");
//// String sendStr = "5803004900021914";
// ByteBuf buffer = getByteBuf(ctx, sendStr);
// // 2.发送数据
// ctx.channel().writeAndFlush(buffer);
// log.info("客户端再次往服务端发送数据" + sendStr);
}
}
} else {
log.info(receiveStr);
receiveStr = null;
ctx.flush();
ctx.close();
}
// if (receiveStr.contains("c0a801fc")) { // 冷量计
//
// // 生成对应的采集指令
// deviceManageEntityList = deviceManageService.queryDevicesByType("3");
// size = deviceManageEntityList.size();
//
// log.info("初始连接报文: " + receiveStr);
// IP = receiveStr;
// receiveStr = "";
// // 1.创建将要写出的数据
// String collectionNum = deviceManageEntityList.get(0).getCollectionNum();
// String sendStr = GetReadOrder485.createCloudOrder(collectionNum,"34");
//// String sendStr = "5803004900021914";
// ByteBuf buffer = getByteBuf(ctx,sendStr);
// // 2.发送数据
// ctx.channel().writeAndFlush(buffer);
// } else if (receiveStr.contains("c0a801f0")) { // 电表
//
// // 生成对应的采集指令
// deviceManageEntityList = deviceManageService.queryDevicesByType("1");
// size = deviceManageEntityList.size();
//
// log.info("初始连接报文: " + receiveStr);
// IP = receiveStr;
// receiveStr = "";
// // 1.创建将要写出的数据
//// String sendStr = "6830043080000068110432326536C816"; // 网络单相电表
//// String sendStr = "FEFEFEFE6880025007000068010243C3B216"; // 广仪三相电表
// String collectionNum = deviceManageEntityList.get(0).getCollectionNum();
// String sendStr = GetReadOrder485.createMeterOrder(collectionNum,"1");
// ByteBuf buffer = getByteBuf(ctx,sendStr);
// // 2.发送数据
// ctx.channel().writeAndFlush(buffer);
// } else if ((receiveStr.length() == 18) && (IP.contains("c0a801fc"))) {
// analysisReceiveOrder485.analysisCloudOrder485(receiveStr); // 解析冷量计
// receiveStr = "";
// // 1.创建将要写出的数据
//// String sendStr = "5803004900021914";
// num = num + 1;
// Thread.sleep(1000);
// if (num >= size-1) {
// num = 0;
// // 关闭连接
// receiveStr = null;
// ctx.close();
// } else {
// String collectionNum = deviceManageEntityList.get(num).getCollectionNum();
// String sendStr = GetReadOrder485.createCloudOrder(collectionNum, "34");
// ByteBuf buffer = getByteBuf(ctx, sendStr);
// // 2.发送数据
// ctx.channel().writeAndFlush(buffer);
// log.info("客户端再次往服务端发送数据" + num);
// }
//
// } else if ((receiveStr.length() == 44) && (IP.contains("c0a801f0"))) {
// analysisReceiveOrder485.analysisMeterOrder485(receiveStr); // 解析电表
// receiveStr = "";
// num = num + 1;
// Thread.sleep(1000);
// if (num >= size-1) {
// num = 0;
// receiveStr = null;
// // 关闭连接
// ctx.close();
// } else {
// // 1.创建将要写出的数据
// // fe fe fe fe 68 80 02 50 07 00 00 68 81 06 43 c3 8c 34 33 33 5c 16
//// String sendStr = "FEFEFE6880025007000068010243C3B216";
// String collectionNum = deviceManageEntityList.get(num).getCollectionNum();
// String sendStr = GetReadOrder485.createMeterOrder(collectionNum, "1");
// ByteBuf buffer = getByteBuf(ctx, sendStr);
// // 2.发送数据
// ctx.channel().writeAndFlush(buffer);
// log.info("客户端再次往服务端发送数据" + num);
// }
// } else if ((receiveStr.length() > 44)) {
// log.info(receiveStr);
// receiveStr = null;
// ctx.flush();
// ctx.close();
// }
ctx.flush();
}
}

179
user-service/src/main/java/com/mh/user/netty/NettyEchoServer.java

@ -1,179 +0,0 @@
package com.mh.user.netty;
import com.mh.user.utils.ExchangeStringUtil;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import java.io.IOException;
import java.net.InetSocketAddress;
/**
* @author ljf
* @title Netty
* @description netty 使用
* @updateTime 2020-04-21
* @throws
*/
@Slf4j
public class NettyEchoServer {
public void bind(int port) throws Exception {
// accept线程组,用来接收连接
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
// IO 线程组,用来处理业务逻辑
EventLoopGroup workerGroup = new NioEventLoopGroup(1);
try {
// 服务端启动引导
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup,workerGroup) // 绑定两个线程
.channel(NioServerSocketChannel.class) // 指定通道类型
.option(ChannelOption.SO_BACKLOG, 1024) // 设置TCP连接的缓冲区
.handler(new LoggingHandler(LogLevel.INFO)) // 设置日志级别
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
ChannelPipeline pipeline = socketChannel.pipeline(); // 获取处理器链
pipeline.addLast(new EchoServerHandler()); // 添加新的事件处理器
}
});
// 通过bind启动服务
ChannelFuture f = serverBootstrap.bind(port).sync();
// 阻塞主线程,知道网络服务被关闭
f.channel().closeFuture().sync();
} catch (Exception e){
e.printStackTrace();
} finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}
static class EchoServerHandler extends ChannelHandlerAdapter {
// 每当从客户端收到新的数据时,这个方法会在收到消息时被调用
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
try {
ByteBuf buf = (ByteBuf)msg;
byte [] bytes = new byte[buf.readableBytes()];
buf.readBytes(bytes);//复制内容到字节数组bytes
String receiveStr = ExchangeStringUtil.bytesToHexString(bytes);//将接收到的数据转为字符串,此字符串就是客户端发送的字符串
log.info("接收到的数据: "+ receiveStr);
//返回16进制到客户端
writeToClient(receiveStr,ctx,"测试");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// ctx.write(Unpooled.wrappedBuffer("Server message".getBytes()));
// ctx.fireChannelRead(msg);
}
// 数据读取完后被调用
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.flush();
}
// 当Netty由于IO错误或者处理器在处理事件时抛出的异常时被调用
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
/**
* 客户端与服务端第一次建立连接时 执行
*
* @param ctx
* @throws Exception
*/
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception, IOException
{
super.channelActive(ctx);
ctx.channel().read();
InetSocketAddress ifsock = (InetSocketAddress) ctx.channel().remoteAddress();
String clientIp = ifsock.getAddress().getHostAddress();
//此处不能使用ctx.close(),否则客户端始终无法与服务端建立连接
log.info("channelActive: "+clientIp + ctx.name());
}
/**
* 客户端与服务端 断连时 执行
*
* @param ctx
* @throws Exception
*/
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception, IOException
{
super.channelInactive(ctx);
InetSocketAddress ifsock = (InetSocketAddress) ctx.channel().remoteAddress();
String clientIp = ifsock.getAddress().getHostAddress();
ctx.close(); //断开连接时,必须关闭,否则造成资源浪费,并发量很大情况下可能造成宕机
System.out.println("channelInactive:"+clientIp);
}
/**
* 服务端当read超时, 会调用这个方法
*
* @param ctx
* @param evt
* @throws Exception
*/
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception, IOException
{
super.userEventTriggered(ctx, evt);
InetSocketAddress ifsock = (InetSocketAddress) ctx.channel().remoteAddress();
String clientIp = ifsock.getAddress().getHostAddress();
ctx.close();//超时时断开连接
System.out.println("userEventTriggered:"+clientIp);
}
/**
* 公用回写数据到客户端的方法
* @param channel
* @param mark 用于打印/log的输出
* <br>//channel.writeAndFlush(msg);//不行
* <br>//channel.writeAndFlush(receiveStr.getBytes());//不行
* <br>在netty里进出的都是ByteBuf楼主应确定服务端是否有对应的编码器将字符串转化为ByteBuf
*/
private void writeToClient(final String receiveStr, ChannelHandlerContext channel, final String mark) {
try {
ByteBuf buff = Unpooled.buffer();//netty需要用ByteBuf传输
buff.writeBytes(ExchangeStringUtil.hexStrToBinaryStr(receiveStr));//对接需要16进制
channel.writeAndFlush(buff).addListener((ChannelFutureListener) future -> {
StringBuilder sb = new StringBuilder("");
if(!StringUtils.isEmpty(mark)){
sb.append("【").append(mark).append("】");
}
if (future.isSuccess()) {
System.out.println(sb.toString()+"回写成功"+receiveStr);
log.info(sb.toString()+"回写成功"+receiveStr);
} else {
System.out.println(sb.toString()+"回写失败"+receiveStr);
log.error(sb.toString()+"回写失败"+receiveStr);
}
});
} catch (Exception e) {
e.printStackTrace();
System.out.println("调用通用writeToClient()异常"+e.getMessage());
log.error("调用通用writeToClient()异常:",e);
}
}
}
}

97
user-service/src/main/java/com/mh/user/netty/NettyMeterAndCloudClient.java

@ -1,97 +0,0 @@
package com.mh.user.netty;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.timeout.IdleStateHandler;
import io.netty.handler.timeout.ReadTimeoutHandler;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.TimeUnit;
/**
* @author ljf
* @title
* @description Netty客户端采集电表
* @updateTime 2020-05-13
* @throws
*/
@Slf4j
@Setter
@Getter
public class NettyMeterAndCloudClient {
// implements Runnable {
private int port;
private String host;
// 构造函数传递值 继承Thread时需要
public NettyMeterAndCloudClient(int port, String host) {
this.port = port;
this.host = host;
}
public NettyMeterAndCloudClient() {
super();
}
public void connect(int port, String host) throws InterruptedException {
// 配置客户端NIO线程组
EventLoopGroup group = new NioEventLoopGroup(1);
try {
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group).channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY, true)
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 3000)
.option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(1024*1024))
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) {
// 基于换行符号
// socketChannel.pipeline().addLast(new LineBasedFrameDecoder(1024));
// // 解码转String,注意调整自己的编码格式GBK、UTF-8
// socketChannel.pipeline().addLast(new StringDecoder(StandardCharsets.UTF_8));
// // 解码转String,注意调整自己的编码格式GBK、UTF-8
// socketChannel.pipeline().addLast(new StringEncoder(StandardCharsets.UTF_8));
// 超过10秒钟没有数据读取自动断开连接
socketChannel.pipeline().addLast(new IdleStateHandler(10,10,10, TimeUnit.SECONDS));
// 在管道中添加我们自己的接收数据实现方法
// socketChannel.pipeline().addLast(new NettyClientHandler());
socketChannel.pipeline().addLast(new NettyMeterAndCloudClientHandler());
}
});
// 发起异步连接操作
ChannelFuture channelFuture = bootstrap.connect(host, port).sync();
if (channelFuture.isSuccess()) {
log.info("connect server 成功---------");
} else {
log.info("连接失败!");
log.info("准备重连!");
// connect(port, host);
}
// 等待客户端连接链路关闭future.channel().closeFuture().sync(); // 阻塞main线程
channelFuture.channel().closeFuture().sync();
} catch (Exception e) {
log.error(e.getMessage());
} finally {
group.shutdownGracefully();
// try {
// TimeUnit.SECONDS.sleep(5);
// connect(port, host); // 断线重连
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
}
}
//
// @SneakyThrows
// @Override
// public void run() {
// connect(port, host);
// }
}

193
user-service/src/main/java/com/mh/user/netty/NettyMeterAndCloudClientHandler.java

@ -1,193 +0,0 @@
package com.mh.user.netty;
import com.mh.user.constants.Constant;
import com.mh.user.entity.DeviceManageEntity;
import com.mh.user.service.DeviceManageService;
import com.mh.user.utils.*;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.ReferenceCountUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
/**
* @author ljf
* @title
* @description 客户端异步消息处理机制
* @updateTime 2020-05-13
* @throws
*/
@Slf4j
public class NettyMeterAndCloudClientHandler extends ChannelHandlerAdapter {
private int num = 0;
private int size = 0;
private String receiveStr = null;
private int idle_count = 0;
private String IP = "";
private String port = "";
List<DeviceManageEntity> deviceManageEntityList;
// 调用service
ApplicationContext context = SpringBeanUtil.getApplicationContext();
DeviceManageService deviceManageService = context.getBean(DeviceManageService.class);
AnalysisReceiveOrder485 analysisReceiveOrder485 = new AnalysisReceiveOrder485();
@Override
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
log.info("当前channel从EventLoop取消注册");
super.channelUnregistered(ctx);
}
/**
* 超时处理
* 如果120秒没有接受客户端的心跳就触发;
* 如果超过3次则直接关闭;
*/
@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())) { //如果读通道处于空闲状态,说明没有接收到心跳命令
System.out.println("第" + idle_count + "已经20秒没有接收到服务器的信息了,发送的第" + num + "条数据");
if (deviceManageEntityList.get(num) == null) {
ctx.channel().close();
} else {
if (idle_count > 3 || num > size - 1) {
System.out.println("关闭这个不活跃的channel");
ctx.channel().close();
}
SendOrderUtils.sendMeterOrCloud(deviceManageEntityList.get(num), num, IP, port, ctx);
idle_count++;
}
}
} else {
super.userEventTriggered(ctx, obj);
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
log.info("通信异常!!");
Channel incoming = ctx.channel();
if (incoming.isActive()) {
log.info("SimpleClient: " + incoming.remoteAddress() + "异常");
receiveStr = null;
cause.printStackTrace();
ctx.close();
}
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
// super.channelActive(ctx);
// 添加一个状态值,判断是否继续发送指令 update by ljf on 2020-08-07
if (Constant.WEB_FLAG) {
num = 0;
// 关闭连接
receiveStr = null;
ctx.close();
} else {
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss");
Date date = new Date();
log.info(ctx.channel().remoteAddress() + " " + sdf1.format(date) + "链接服务端成功!");
// 截取IP地址
IP = ExchangeStringUtil.getMidString(ctx.channel().remoteAddress() + "", "/", ":");
// 截取端口号
port = ExchangeStringUtil.getMidString(ctx.channel().remoteAddress() + "", ":", "");
log.info("IP: " + IP + ",端口号: " + port);
// 生成对应的采集指令
deviceManageEntityList = deviceManageService.queryDevicesByType(null);
size = deviceManageEntityList.size();
log.info("初始连接报文: " + receiveStr);
receiveStr = "";
// 保持长连接,封装发送电表工具方法 update by ljf on 2021-01-26
SendOrderUtils.sendMeterOrCloud(deviceManageEntityList.get(0), 0, IP, port, ctx);
}
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
Thread.sleep(500);
receiveStr = null;
ctx.close();
log.info(ctx.channel().localAddress() + "退出链接!!");
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
try {
ByteBuf buf = (ByteBuf) msg;
byte[] bytes = new byte[buf.readableBytes()];
buf.readBytes(bytes);//复制内容到字节数组bytes
buf.clear();
log.info("获取到的值: " + ExchangeStringUtil.bytesToHexString(bytes));
if (bytes.length <= 62) {
// if (bytes.length <= 142) {
// receiveStr = receiveStr.replace("null", "");
// receiveStr = receiveStr + ExchangeStringUtil.bytesToHexString(bytes);//将接收到的数据转为字符串,此字符串就是客户端发送的字符串
// log.info(ctx.channel().remoteAddress() + " " + ctx.channel().localAddress() + " 接受服务器数据:" + receiveStr + ",大小: " + receiveStr.length());
receiveStr = receiveStr + ExchangeStringUtil.bytesToHexString(bytes);//将接收到的数据转为字符串,此字符串就是客户端发送的字符串
receiveStr = receiveStr.replace("null", "");
log.info("接受服务器数据:" + receiveStr + ",大小: " + receiveStr.length());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
ReferenceCountUtil.release(msg);
}
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
log.info("采集电表或者冷量计-数据读取接收完成: " + receiveStr);
if ((receiveStr.length() == 36) && (deviceManageEntityList.get(num).getParamId() == 3)) {
// analysisReceiveOrder485.analysisCloudOrder485(receiveStr); // 解析冷量计
} else if ((receiveStr.length() == 62) && (deviceManageEntityList.get(num).getParamId() == 1)) {
// 把receiveStr的"null"值去掉
// a9fec2c71f9002fefefefe6839025007000068810643c3bb446c338d16c2b8
// A9 FE C2 C7 1F 90 02 FE FE FE FE 68 39 02 50 07 00 00 68 81 06 43 C3 5B 38 6C 33 21 16 F8 12
analysisReceiveOrder485.analysisMeterOrder485(receiveStr,"","",""); // 解析电表
}
receiveStr = "";
num = num + 1;
Thread.sleep(600);
if (num > size - 1) {
num = 0;
receiveStr = null;
// 关闭连接
ctx.close();
// // 保持长连接,封装发送电表工具方法 update by ljf on 2021-01-26
// SendOrderUtils.sendMeterOrder(deviceManageEntityList.get(num),num,IP,port,ctx);
} else {
// 添加一个状态值,判断是否继续发送指令 update by ljf on 2020-08-07
if (Constant.WEB_FLAG) {
log.info("有指令下发退出定时采集DDC参数");
num = 0;
// 关闭连接
receiveStr = null;
ctx.close();
} else {
// 封装发送电表工具方法 update by ljf on 2021-01-26
SendOrderUtils.sendMeterOrCloud(deviceManageEntityList.get(num), num, IP, port, ctx);
}
}
ctx.flush();
}
}

96
user-service/src/main/java/com/mh/user/netty/NettyMeterClient.java

@ -1,96 +0,0 @@
package com.mh.user.netty;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.timeout.ReadTimeoutHandler;
import lombok.Getter;
import lombok.Setter;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
/**
* @author ljf
* @title
* @description Netty客户端采集电表
* @updateTime 2020-05-13
* @throws
*/
@Slf4j
@Setter
@Getter
public class NettyMeterClient {
// implements Runnable {
private int port;
private String host;
// 构造函数传递值 继承Thread时需要
public NettyMeterClient(int port, String host) {
this.port = port;
this.host = host;
}
public NettyMeterClient() {
super();
}
public void connect(int port, String host) throws InterruptedException {
// 配置客户端NIO线程组
// 配置客户端NIO线程组
EventLoopGroup group = new NioEventLoopGroup(1);
try {
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group).channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY, true)
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 3000)
.option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(1024*1024))
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) {
// 基于换行符号
// socketChannel.pipeline().addLast(new LineBasedFrameDecoder(1024));
// // 解码转String,注意调整自己的编码格式GBK、UTF-8
// socketChannel.pipeline().addLast(new StringDecoder(StandardCharsets.UTF_8));
// // 解码转String,注意调整自己的编码格式GBK、UTF-8
// socketChannel.pipeline().addLast(new StringEncoder(StandardCharsets.UTF_8));
// 超过10秒钟没有数据读取自动断开连接
socketChannel.pipeline().addLast(new ReadTimeoutHandler(20));
// 在管道中添加我们自己的接收数据实现方法
// socketChannel.pipeline().addLast(new NettyClientHandler());
socketChannel.pipeline().addLast(new NettyMeterClientHandler1());
}
});
// 发起异步连接操作
ChannelFuture channelFuture = bootstrap.connect(host, port).sync();
if (channelFuture.isSuccess()) {
log.info("connect server 成功---------");
} else {
log.info("连接失败!");
log.info("准备重连!");
// connect(port, host);
}
// 等待客户端连接链路关闭future.channel().closeFuture().sync(); // 阻塞main线程
channelFuture.channel().closeFuture().sync();
} catch (Exception e) {
log.error(e.getMessage());
} finally {
group.shutdownGracefully();
// try {
// TimeUnit.SECONDS.sleep(5);
// connect(port, host); // 断线重连
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
}
}
//
// @SneakyThrows
// @Override
// public void run() {
// connect(port, host);
// }
}

143
user-service/src/main/java/com/mh/user/netty/NettyMeterClientHandler.java

@ -1,143 +0,0 @@
//package com.mh.user.netty;
//
//import com.mh.user.entity.DeviceManageEntity;
//import com.mh.user.service.DeviceManageService;
//import com.mh.user.utils.AnalysisReceiveOrder485;
//import com.mh.user.utils.ExchangeStringUtil;
//import com.mh.user.utils.GetReadOrder485;
//import com.mh.user.utils.SpringBeanUtil;
//import io.netty.buffer.ByteBuf;
//import io.netty.channel.Channel;
//import io.netty.channel.ChannelHandlerAdapter;
//import io.netty.channel.ChannelHandlerContext;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.context.ApplicationContext;
//
//import java.text.SimpleDateFormat;
//import java.util.Date;
//import java.util.List;
//
///**
// * @author ljf
// * @title :
// * @description :客户端异步消息处理机制
// * @updateTime 2020-05-13
// * @throws :
// */
//@Slf4j
//public class NettyMeterClientHandler extends ChannelHandlerAdapter {
//
// private static int num = 0;
// private static int size = 0;
// private static String receiveStr = "";
// private static String IP = "";
// List<DeviceManageEntity> deviceManageEntityList;
//
// // 调用service
// ApplicationContext context = SpringBeanUtil.getApplicationContext();
// DeviceManageService deviceManageService = context.getBean(DeviceManageService.class);
//
// AnalysisReceiveOrder485 analysisReceiveOrder485;
//
// // 到处理IO事件,异常抛出时调用,已丢弃
// @Override
// public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
// Channel incoming = ctx.channel();
// if (!incoming.isActive()){
// log.info("通信异常!!");
// receiveStr = "";
// log.info("SimpleClient: " + incoming.remoteAddress() + "异常");
// cause.printStackTrace();
// ctx.close();
// }
// }
//
// @Override
// public void channelActive(ChannelHandlerContext ctx) throws Exception {
// SimpleDateFormat sdf1=new SimpleDateFormat("yyyy-mm-dd HH:mm:ss");
// Date date=new Date();
// log.info(sdf1.format(date) + "链接服务端成功!");
// }
//
// private ByteBuf getByteBuf(ChannelHandlerContext ctx, String sendStr) {
// // byte类型的数据
//// byte[] bytes = "这里是将要写往服务端的数据".getBytes(Charset.forName("utf-8"));
//// String sendStr = "5803004900021914"; // 冷量计
// // 申请一个数据结构存储信息
// ByteBuf buffer = ctx.alloc().buffer();
// // 将信息放入数据结构中
// buffer.writeBytes(ExchangeStringUtil.hexStrToBinaryStr(sendStr));//对接需要16进制
// return buffer;
// }
//
// @Override
// public void channelInactive(ChannelHandlerContext ctx) throws Exception {
// Thread.sleep(500);
// ctx.close();
// log.info("退出链接!!");
// }
//
// @Override
// public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
//// ByteBuf buf = (ByteBuf)msg;
//// byte[] req = new byte[buf.readableBytes()];
//// buf.readBytes(req);
//// String body = new String(req, "UTF-8");
// ByteBuf buf = (ByteBuf)msg;
// byte [] bytes = new byte[buf.readableBytes()];
// buf.readBytes(bytes);//复制内容到字节数组bytes
// receiveStr = receiveStr + ExchangeStringUtil.bytesToHexString(bytes);//将接收到的数据转为字符串,此字符串就是客户端发送的字符串
// log.info("接受服务器数据:" + receiveStr + ",大小: " + receiveStr.length());
// }
//
// @Override
// public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
// log.info("数据读取接收完成");
// if (receiveStr.contains("c0a801f0")) { // 电表
//
// // 生成对应的采集指令
// deviceManageEntityList = deviceManageService.queryDevicesByType("1");
// size = deviceManageEntityList.size();
//
// log.info("初始连接报文: " + receiveStr);
// IP = receiveStr;
// receiveStr = "";
// num = 0;
// // 1.创建将要写出的数据
//// String sendStr = "6830043080000068110432326536C816"; // 网络单相电表
//// String sendStr = "FEFEFEFE6880025007000068010243C3B216"; // 广仪三相电表
// String collectionNum = deviceManageEntityList.get(num).getCollectionNum();
// String sendStr = GetReadOrder485.createMeterOrder(collectionNum,"1");
// ByteBuf buffer = getByteBuf(ctx,sendStr);
// // 2.发送数据
// ctx.channel().writeAndFlush(buffer);
// } else if ((receiveStr.length() == 44) && (IP.contains("c0a801f0"))) {
// analysisReceiveOrder485.analysisMeterOrder485(receiveStr); // 解析电表
// receiveStr = "";
// num = num + 1;
// Thread.sleep(1000);
// if (num >= size-1) {
// num = 0;
// // 关闭连接
// ctx.close();
// } else {
// // 1.创建将要写出的数据
// // fe fe fe fe 68 80 02 50 07 00 00 68 81 06 43 c3 8c 34 33 33 5c 16
//// String sendStr = "FEFEFE6880025007000068010243C3B216";
// String collectionNum = deviceManageEntityList.get(num).getCollectionNum();
// String sendStr = GetReadOrder485.createMeterOrder(collectionNum, "1");
// ByteBuf buffer = getByteBuf(ctx, sendStr);
// // 2.发送数据
// ctx.channel().writeAndFlush(buffer);
// log.info("客户端再次往服务端发送数据" + num);
// }
// } else if ((receiveStr.length() > 44)) {
// log.info(receiveStr);
// receiveStr = "";
// ctx.flush();
// ctx.close();
// }
// ctx.flush();
// }
//
//}

259
user-service/src/main/java/com/mh/user/netty/NettyMeterClientHandler1.java

@ -1,259 +0,0 @@
package com.mh.user.netty;
import com.mh.user.constants.Constant;
import com.mh.user.entity.DeviceManageEntity;
import com.mh.user.service.DeviceManageService;
import com.mh.user.utils.*;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.ReferenceCountUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
/**
* @author ljf
* @title
* @description 客户端异步消息处理机制
* @updateTime 2020-05-13
* @throws
*/
@Slf4j
public class NettyMeterClientHandler1 extends ChannelHandlerAdapter {
private int num = 0;
private int size = 0;
private String receiveStr = null;
private String IP = "";
private String port = "";
List<DeviceManageEntity> deviceManageEntityList;
// 调用service
ApplicationContext context = SpringBeanUtil.getApplicationContext();
DeviceManageService deviceManageService = context.getBean(DeviceManageService.class);
AnalysisReceiveOrder485 analysisReceiveOrder485 = new AnalysisReceiveOrder485();
@Override
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
log.info("当前channel从EventLoop取消注册");
super.channelUnregistered(ctx);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
// super.exceptionCaught(ctx, cause);
log.info("通信异常!!");
// receiveStr = null;
Channel incoming = ctx.channel();
if (incoming.isActive()) {
log.info("SimpleClient: " + incoming.remoteAddress() + "异常");
receiveStr = null;
cause.printStackTrace();
ctx.close();
// receiveStr = null;
// try {
// TimeUnit.SECONDS.sleep(5);
// SocketAddress remoteAddress = ctx.channel().remoteAddress();
// String port = ExchangeStringUtil.endData(remoteAddress.toString(),":");
// String host = ExchangeStringUtil.splitData(remoteAddress.toString(),"/",":");
// NettyClient nettyClient = new NettyClient();
// nettyClient.connect(Integer.parseInt(port), host); // 断线重连
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
}
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
// super.channelActive(ctx);
// 添加一个状态值,判断是否继续发送指令 update by ljf on 2020-08-07
if (Constant.WEB_FLAG) {
num = 0;
// 关闭连接
receiveStr = null;
ctx.close();
} else {
ctx.channel().read();
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss");
Date date = new Date();
log.info(ctx.channel().remoteAddress() + " " + sdf1.format(date) + "链接服务端成功!");
// 截取IP地址
IP = ExchangeStringUtil.getMidString(ctx.channel().remoteAddress() + "", "/", ":");
// 截取端口号
port = ExchangeStringUtil.getMidString(ctx.channel().remoteAddress() + "", ":", "");
log.info("IP: " + IP + ",端口号: " + port);
// 生成对应的采集指令
// 修改生成指令(冷量计和电量一起采集) update by ljf on 2021-01-27
deviceManageEntityList = deviceManageService.queryDevicesByType(null);
size = deviceManageEntityList.size();
log.info("初始连接报文: " + receiveStr);
receiveStr = "";
// 保持长连接,封装发送电表工具方法 update by ljf on 2021-01-26
SendOrderUtils.sendMeterOrder(deviceManageEntityList.get(0), 0, IP, port, ctx);
// 1.创建将要写出的数据
// String sendStr = "6830043080000068110432326536C816"; // 网络单相电表
// String sendStr = "FEFEFEFE6880025007000068010243C3B216"; // 广仪三相电表
// String collectionNum = deviceManageEntityList.get(0).getCollectionNum();
// String sendStr = GetReadOrder485.createMeterOrder(IP, port,
// deviceManageEntityList.get(0).getDataCom(), collectionNum, "1");
//// FileUtils.createFileAndWrite(sendStr, 0);
// ByteBuf buffer = getByteBuf(ctx, sendStr);
// // 2.发送数据
// ctx.channel().writeAndFlush(buffer);
}
}
private ByteBuf getByteBuf(ChannelHandlerContext ctx, String sendStr) {
// byte类型的数据
// byte[] bytes = "这里是将要写往服务端的数据".getBytes(Charset.forName("utf-8"));
// String sendStr = "5803004900021914"; // 冷量计
// 申请一个数据结构存储信息
ByteBuf buffer = ctx.alloc().buffer();
// 将信息放入数据结构中
buffer.writeBytes(ExchangeStringUtil.hexStrToBinaryStr(sendStr));//对接需要16进制
return buffer;
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
Thread.sleep(500);
receiveStr = null;
ctx.close();
log.info(ctx.channel().localAddress() + "退出链接!!");
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
try {
ByteBuf buf = (ByteBuf) msg;
byte[] bytes = new byte[buf.readableBytes()];
buf.readBytes(bytes);//复制内容到字节数组bytes
buf.clear();
log.info("获取到的值: " + ExchangeStringUtil.bytesToHexString(bytes));
if (bytes.length <= 62) {
// if (bytes.length <= 142) {
// receiveStr = receiveStr.replace("null", "");
// receiveStr = receiveStr + ExchangeStringUtil.bytesToHexString(bytes);//将接收到的数据转为字符串,此字符串就是客户端发送的字符串
// log.info(ctx.channel().remoteAddress() + " " + ctx.channel().localAddress() + " 接受服务器数据:" + receiveStr + ",大小: " + receiveStr.length());
receiveStr = receiveStr + ExchangeStringUtil.bytesToHexString(bytes);//将接收到的数据转为字符串,此字符串就是客户端发送的字符串
receiveStr = receiveStr.replace("null", "");
log.info("接受服务器数据:" + receiveStr + ",大小: " + receiveStr.length());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
ReferenceCountUtil.release(msg);
}
// super.channelRead(ctx, msg);
// ByteBuf buf = (ByteBuf)msg;
// byte[] req = new byte[buf.readableBytes()];
// buf.readBytes(req);
// String body = new String(req, "UTF-8");
// ByteBuf buf = (ByteBuf)msg;
// byte [] bytes = new byte[buf.readableBytes()];
// buf.readBytes(bytes);//复制内容到字节数组bytes
// log.info("获取到的值: " + ExchangeStringUtil.bytesToHexString(bytes));
// if (bytes.length != 0) {
//// receiveStr = receiveStr.replace("null", "");
//// receiveStr = receiveStr + ExchangeStringUtil.bytesToHexString(bytes);//将接收到的数据转为字符串,此字符串就是客户端发送的字符串
//// log.info(ctx.channel().remoteAddress() + " " + ctx.channel().localAddress() + " 接受服务器数据:" + receiveStr + ",大小: " + receiveStr.length());
// receiveStr = receiveStr + ExchangeStringUtil.bytesToHexString(bytes);//将接收到的数据转为字符串,此字符串就是客户端发送的字符串
// receiveStr = receiveStr.replace("null", "");
// log.info("接受服务器数据:" + receiveStr + ",大小: " + receiveStr.length());
// }
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
log.info("采集电表-数据读取接收完成: " + receiveStr);
// 把receiveStr的"null"值去掉
// a9fec2c71f9002fefefefe6839025007000068810643c3bb446c338d16c2b8
// A9 FE C2 C7 1F 90 02 FE FE FE FE 68 39 02 50 07 00 00 68 81 06 43 C3 5B 38 6C 33 21 16 F8 12
if ((receiveStr.length() == 62)) {
// log.info(receiveStr);
analysisReceiveOrder485.analysisMeterOrder485(receiveStr,"","",""); // 解析电表
receiveStr = "";
num = num + 1;
Thread.sleep(600);
if (num > size - 1) {
num = 0;
receiveStr = null;
// 关闭连接
ctx.close();
// // 保持长连接,封装发送电表工具方法 update by ljf on 2021-01-26
// SendOrderUtils.sendMeterOrder(deviceManageEntityList.get(num),num,IP,port,ctx);
} else {
// 添加一个状态值,判断是否继续发送指令 update by ljf on 2020-08-07
if (Constant.WEB_FLAG) {
log.info("有指令下发退出定时采集DDC参数");
num = 0;
// 关闭连接
receiveStr = null;
ctx.close();
} else {
// 封装发送电表工具方法 update by ljf on 2021-01-26
SendOrderUtils.sendMeterOrder(deviceManageEntityList.get(num), num, IP, port, ctx);
// 1.创建将要写出的数据
// fe fe fe fe 68 80 02 50 07 00 00 68 81 06 43 c3 8c 34 33 33 5c 16
// String sendStr = "FEFEFE6880025007000068010243C3B216";
// String collectionNum = deviceManageEntityList.get(num).getCollectionNum();
// String sendStr = GetReadOrder485.createMeterOrder(IP, port,
// deviceManageEntityList.get(num).getDataCom(), collectionNum, "1");
// ByteBuf buffer = getByteBuf(ctx, sendStr);
// // 2.发送数据
// ctx.channel().writeAndFlush(buffer);
// log.info("客户端再次往服务端发送数据" + num);
}
}
} else if ((receiveStr.length() > 62)) {
receiveStr = null;
num = num + 1;
Thread.sleep(500);
if (num > size - 1) {
num = 0;
receiveStr = null;
// 关闭连接
ctx.close();
// // 保持长连接,封装发送电表工具方法 update by ljf on 2021-01-26
// SendOrderUtils.sendMeterOrder(deviceManageEntityList.get(num),num,IP,port,ctx);
} else {
// 添加一个状态值,判断是否继续发送指令 update by ljf on 2020-08-07
if (Constant.WEB_FLAG) {
log.info("有指令下发退出定时采集DDC参数");
num = 0;
// 关闭连接
receiveStr = null;
ctx.close();
} else {
// 封装发送电表工具方法 update by ljf on 2021-01-26
SendOrderUtils.sendMeterOrder(deviceManageEntityList.get(num), num, IP, port, ctx);
// 1.创建将要写出的数据
// fe fe fe fe 68 80 02 50 07 00 00 68 81 06 43 c3 8c 34 33 33 5c 16
// String sendStr = "FEFEFE6880025007000068010243C3B216";
// String collectionNum = deviceManageEntityList.get(num).getCollectionNum();
// String sendStr = GetReadOrder485.createMeterOrder(IP, port,
// deviceManageEntityList.get(num).getDataCom(), collectionNum, "1");
// ByteBuf buffer = getByteBuf(ctx, sendStr);
// // 2.发送数据
// ctx.channel().writeAndFlush(buffer);
// log.info("客户端再次往服务端发送数据" + num);
}
}
}
ctx.flush();
}
}

215
user-service/src/main/java/com/mh/user/serialport/SendAndReceiveByCom.java

@ -0,0 +1,215 @@
package com.mh.user.serialport;
import com.mh.common.utils.StringUtils;
import com.mh.user.constants.Constant;
import com.mh.user.entity.DeviceCodeParamEntity;
import com.mh.user.factory.Device;
import com.mh.user.factory.DeviceFactory;
import com.mh.user.service.BuildingService;
import com.mh.user.service.DeviceInstallService;
import com.mh.user.service.NowDataService;
import com.mh.user.service.SysParamService;
import com.mh.user.strategy.DeviceStrategy;
import com.mh.user.strategy.DeviceStrategyFactory;
import com.mh.user.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import purejavacomm.SerialPort;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author LJF
* @version 1.0
* @project CHWS
* @description 通过串口发送和接收数据
* @date 2024-03-18 14:56:32
*/
@Slf4j
public class SendAndReceiveByCom {
List<DeviceCodeParamEntity> deviceManageEntityList;
ApplicationContext context = SpringBeanUtil.getApplicationContext();
DeviceInstallService deviceInstallService = context.getBean(DeviceInstallService.class);
NowDataService nowDataService = context.getBean(NowDataService.class);
BuildingService buildingService = context.getBean(BuildingService.class);
public void sendAndReceive(String sort, String thread) {
SerialPort serialPort = null;
CacheUtil cacheUtil = CacheUtil.getInstance();
try {
//生成对应的采集指令
List<DeviceCodeParamEntity> deviceParamsByType = cacheUtil.getDeviceParamsByType(sort);
deviceManageEntityList = deviceParamsByType
.parallelStream()
.filter(value -> value.getThread().equals(thread))
.sorted(Comparator.comparing(DeviceCodeParamEntity::getDataCom))
.collect(Collectors.toList());
int size = deviceManageEntityList.size();
for (int i = 0; i < size; i++) {
//判断网页端是否有操作设备的
if (Constant.WEB_FLAG) {
if (serialPort != null) {
SerialTool.closePort(serialPort);
}
log.info("有指令下发退出定时采集");
break;
}
String comName = deviceManageEntityList.get(i).getDataCom();
if (StringUtils.isBlank(comName)) {
log.info("-------------串口:" + comName + "不存在!-------------");
continue;
}
//获取设备实际波特率
int baudrate = deviceManageEntityList.get(i).getBaudrate();
//获取设备实际校验位
String parity = deviceManageEntityList.get(i).getParity();
String deviceAddr = deviceManageEntityList.get(i).getDeviceAddr();
String deviceType = deviceManageEntityList.get(i).getDeviceType();
String registerAddr = deviceManageEntityList.get(i).getRegisterAddr();
String brand = deviceManageEntityList.get(i).getBrand();//品牌
String buildingId = deviceManageEntityList.get(i).getBuildingId();
String buildingName = buildingService.queryBuildingName(buildingId); //查询楼栋名称
// 创建设备报文
Device device = DeviceFactory.createDevice(deviceType);
DeviceStrategy strategy = DeviceStrategyFactory.createStrategy(deviceType);
if (null == strategy) {
continue;
}
device.setStrategy(strategy);
String sendStr = device.createOrders(deviceManageEntityList.get(i));
try {
//传入对应的串口参数并打开串口
if (StringUtils.isBlank(parity) || parity.equalsIgnoreCase("none")) {
serialPort = SerialTool.openPort(comName, baudrate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
} else {
serialPort = SerialTool.openPort(comName, baudrate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_EVEN);
}
if (null == serialPort) {
continue;
}
//向串口发送指令
if (StringUtils.isBlank(sendStr)) {
continue;
}
SerialTool.sendToPort(SerialTool.HexString2Bytes(sendStr), serialPort, sendStr, deviceType);
if (deviceType.equals("热泵")) {
for (int j = 0; j < 4; j++) {
Thread.sleep(1000);
// 判断网页端是否有操作设备的
if (Constant.WEB_FLAG) {
SerialTool.closePort(serialPort);
log.info("有指令下发退出定时采集");
break;
}
}
} else {
Thread.sleep(2000);
}
//从串口读取数据
byte[] bytes = SerialTool.readFromPort(serialPort);
Date date1 = new Date();
String dateStr = DateUtil.dateToString(date1, "yyyy-MM-dd HH:mm:ss");
if (bytes == null) {
SerialTool.closePort(serialPort);
log.info("串口" + serialPort.getName() + "没有数据返回!" + i);
log.info("----------------" + deviceType + "离线,设备号:" + deviceAddr + ",所属楼栋:" + buildingName + "----------------");
String time1 = deviceInstallService.selectLastDate(deviceType, deviceAddr, buildingId);
if (time1 == null) {
time1 = dateStr;
}
int d = ExchangeStringUtil.compareCopyTime(time1, dateStr);
if (d == 1) {
deviceInstallService.updateNotOnline(deviceAddr, deviceType, buildingId, "离线"); //所有设备离线
if (deviceType.equals("热泵")) {
nowDataService.updateRunState(buildingId, deviceAddr, "离线", buildingName); //监控界面状态表热泵在线状态
}
}
continue;
}
// 处理返回来的数据报文
dealReceiveData(dateStr, serialPort, i, deviceAddr, deviceType, registerAddr, brand, buildingId, buildingName, bytes, device);
} catch (Exception e) {
if (null != serialPort) {
SerialTool.closePort(serialPort);
log.error("发送窗口数据异常==>", e);
}
} finally {
if (null != serialPort) {
SerialTool.closePort(serialPort);
log.info("关闭串口==" + serialPort.getName());
}
}
}
} catch (Exception e) {
log.error("-------------串口采集异常!----------->>", e);
}
}
/**
* 处理返回来的数据
*
* @param dateStr
* @param serialPort
* @param i
* @param deviceAddr
* @param deviceType
* @param registerAddr
* @param brand
* @param buildingId
* @param buildingName
* @param bytes
* @throws InterruptedException
*/
private void dealReceiveData(String dateStr,
SerialPort serialPort,
int i,
String deviceAddr,
String deviceType,
String registerAddr,
String brand,
String buildingId,
String buildingName, byte[] bytes, Device device) {
try {
String receiveStr = "";
receiveStr = ExchangeStringUtil.parseByte2HexStr(bytes);
//去掉空格和null
receiveStr = receiveStr.replace("null", "");
receiveStr = receiveStr.replace(" ", "");
log.info("串口:" + serialPort.getName() + ",接受第" + i + "数据:" + receiveStr + ",大小: " + receiveStr.length());
//返回值全部变成大写
String receiveData = receiveStr.toUpperCase();
//截取去掉FE
String dataStr;
if (receiveData.length() > 8) {
String str1 = receiveData.substring(0, 8);
String str2 = receiveData.substring(8);
dataStr = str1.replace("FE", "") + str2;
} else {
dataStr = receiveData.replace("FE", "");
}
deviceInstallService.updateOnline(deviceAddr, deviceType, buildingId, "在线"); //设备在线
log.info("----------------" + deviceType + "在线,设备号:" + deviceAddr + ",所属楼栋:" + buildingName + "----------------");
if (deviceType.equals("热泵")) {
String strState = nowDataService.selectState(buildingId, deviceAddr);
if (strState != null && strState.equals("离线")) { //采集到数据
nowDataService.updateRunState(buildingId, deviceAddr, "不运行", buildingName); //监控界面状态表热泵在线状态
}
}
// 解析返回来的数据
device.analysisReceiveData(dateStr, deviceType, registerAddr, brand, buildingId, buildingName, dataStr);
} catch (Exception e) {
log.error("楼栋:" + buildingName + "设备类型:" + deviceType + "保存数据库失败!" + i, e);
}
}
}

306
user-service/src/main/java/com/mh/user/serialport/SerialPortSendReceive.java

@ -1,306 +0,0 @@
package com.mh.user.serialport;
import com.mh.user.constants.Constant;
import com.mh.user.entity.DeviceCodeParamEntity;
import com.mh.user.service.BuildingService;
import com.mh.user.service.DeviceCodeParamService;
import com.mh.user.service.DeviceInstallService;
import com.mh.user.service.NowDataService;
import com.mh.user.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import gnu.io.SerialPort;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @author nxr
* @title
* @description 串口发送和接收处理,采集类
* @updateTime 2022-08-10
* @throws
*/
@Slf4j
public class SerialPortSendReceive {
private String receiveStr = null;
public SerialPort serialPort = null;
private int size = 0;
private int baudrate=9600;
private String parity=null;
List<DeviceCodeParamEntity> deviceManageEntityList;
// 调用service
ApplicationContext context = SpringBeanUtil.getApplicationContext();
DeviceCodeParamService deviceCodeParamService = context.getBean(DeviceCodeParamService.class);
DeviceInstallService deviceInstallService = context.getBean(DeviceInstallService.class);
NowDataService nowDataService = context.getBean(NowDataService.class);
BuildingService buildingService = context.getBean(BuildingService.class);
AnalysisReceiveOrder485 analysisReceiveOrder485 = new AnalysisReceiveOrder485();
public void serialPortSend(String sort,String thread) {
//查看所有串口
SerialPortUtil serialPortUtil = SerialPortUtil.getSerialPortUtil();
ArrayList<String> port = serialPortUtil.findPort();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date();
String dateStr = df.format(date);
// SerialTool serialPortUtil = SerialTool.getSerialPortUtil();
// ArrayList<String> port = serialPortUtil.findPort();
// comName=comName.toUpperCase(); //转为大写
// if (port.contains(comName)){
try{
//生成对应的采集指令
if (sort.equals("1")){ //水温、水位
deviceManageEntityList = deviceCodeParamService.queryCodeParam3(thread);
}else if (sort.equals("2")){ //采集水、电、运行状态!
deviceManageEntityList = deviceCodeParamService.queryCodeParam4(thread);
}else if (sort.equals("3")){ //采集设定温度、设定水位、故障状态!
deviceManageEntityList = deviceCodeParamService.queryCodeParam5(thread);
}else{
deviceManageEntityList = deviceCodeParamService.queryCodeParam3(thread);
}
size = deviceManageEntityList.size();
for (int i=0;i<size;i++){
//判断网页端是否有操作设备的
if (Constant.WEB_FLAG) {
Constant.FLAG=false;
serialPortUtil.closePort(serialPort);
// Thread.sleep(2000);
log.info("有指令下发退出定时采集");
break;
}
//获取设备实际波特率
baudrate=deviceManageEntityList.get(i).getBaudrate();
//获取设备实际校验位
parity=deviceManageEntityList.get(i).getParity();
String comName=deviceManageEntityList.get(i).getDataCom();
comName=comName.toUpperCase(); //转为大写
if (port.contains(comName)){
String deviceAddr=deviceManageEntityList.get(i).getDeviceAddr();
String deviceType=deviceManageEntityList.get(i).getDeviceType();
String registerAddr=deviceManageEntityList.get(i).getRegisterAddr();
String brand=deviceManageEntityList.get(i).getBrand();//品牌
String buildingId=deviceManageEntityList.get(i).getBuildingId();
String buildingName=buildingService.queryBuildingName(buildingId); //查询楼栋名称
try{
//传入对应的串口参数并打开串口
if (parity==null || parity.equals("") || parity.equalsIgnoreCase("none")){
serialPort = serialPortUtil.openPort(comName, baudrate, SerialPort.DATABITS_8, SerialPort.PARITY_NONE, SerialPort.PARITY_ODD);
}else{
serialPort = serialPortUtil.openPort(comName, baudrate, SerialPort.DATABITS_8, SerialPort.PARITY_EVEN, SerialPort.PARITY_ODD);
}
//向串口发送指令
if (serialPort != null) {
// log.info("---------波特率:"+baudrate+",校验位:"+parity+" -----------");
SendOrderUtils.sendSerialPort(deviceManageEntityList.get(i), serialPort);
if (deviceType.equals("热泵")){
Thread.sleep(4000);
}else{
Thread.sleep(2000);
}
}else{
continue; //continue时,跳出本次循环,继续执行下次循环。Break时,跳出循环(结束循环),执行下面的语句。
}
}catch (Exception e){
// e.printStackTrace();
Constant.WEB_FLAG=false;//可以采集的状态
if(i==size-1){
Constant.FLAG=false;
}
}
receiveStr="";
//从串口读取数据
byte[] bytes= serialPortUtil.readFromPort(serialPort);
try {
String byteStr = new String(bytes, 0, bytes.length).trim();
} catch (NullPointerException e) {
serialPortUtil.closePort(serialPort);
Thread.sleep(2000);
log.info("串口"+serialPort+"没有数据返回!"+i);
log.info("----------------"+deviceType+"离线,设备号:"+deviceAddr+",所属楼栋:"+buildingName+"----------------");
Constant.WEB_FLAG=false;//可以采集的状态
if(i==size-1){
Constant.FLAG=false;
}
String time1=deviceInstallService.selectLastDate(deviceType,deviceAddr,buildingId);
Date date1=new Date();
String time2=df.format(date1);
if (time1==null){
time1=df.format(date1);
}
int d= ExchangeStringUtil.compareCopyTime(time1,time2);
if (d==1){
deviceInstallService.updateNotOnline(deviceAddr,deviceType,buildingId,"离线"); //所有设备离线
if (deviceType.equals("热泵")){
nowDataService.updateRunState(buildingId,deviceAddr,"离线"); //监控界面状态表热泵在线状态
}
}
continue;
}
receiveStr = receiveStr + printHexString(bytes);
//去掉空格和null
receiveStr = receiveStr.replace("null", "");
receiveStr = receiveStr.replace(" ", "");
log.info("串口"+serialPort+"接受第"+i+"数据:" + receiveStr + ",大小: " + receiveStr.length());
try{
serialPortUtil.closePort(serialPort);
log.info("关闭"+serialPort);
}catch (Exception e){
// e.printStackTrace();
Constant.WEB_FLAG=false;//可以采集的状态
if(i==size-1){
Constant.FLAG=false;
}
log.error("关闭"+serialPort+"失败!");
}
//返回值全部变成大写
String receiveData = receiveStr.toUpperCase();
//截取去掉FE
String dataStr;
if (receiveData.length()>8){
String str1=receiveData.substring(0,8);
String str2=receiveData.substring(8);
dataStr=str1.replace("FE", "")+str2;
}else{
dataStr = receiveData.replace("FE", "");
}
deviceInstallService.updateOnline(deviceAddr,deviceType,buildingId,"在线"); //设备在线
log.info("----------------"+deviceType+"在线,设备号:"+deviceAddr+",所属楼栋:"+buildingName+"----------------");
if (deviceType.equals("热泵")){
String strState=nowDataService.selectState(buildingId,deviceAddr);
if (strState!=null && strState.equals("离线")){ //采集到数据
nowDataService.updateRunState(buildingId,deviceAddr,"不运行"); //监控界面状态表热泵在线状态
}
}
try{
if ((dataStr.length() == 36 || dataStr.length() == 44 || dataStr.length()==40 || dataStr.length()==50) && deviceType.equals("电表")) {
analysisReceiveOrder485.analysisMeterOrder485(dataStr,registerAddr,brand,buildingId);
nowDataService.proWaterLevel(dateStr,buildingId); //保存时间点楼栋水位
}else if ((dataStr.length() == 18 || dataStr.length() == 70 || dataStr.length() == 44) && deviceType.equals("水表")) {
analysisReceiveOrder485.analysisWtMeterOrder485(dataStr,registerAddr,brand,buildingId);
}else if (deviceType.equals("压变")) {
analysisReceiveOrder485.analysisPressureOrder485(dataStr,registerAddr,brand,buildingId);
}else if (deviceType.equals("热泵")) {
analysisReceiveOrder485.analysisPumpOrder485(dataStr,registerAddr,brand,buildingId);
}else if (deviceType.equals("温控")) {
analysisReceiveOrder485.analysisTempOrder485(dataStr,registerAddr,brand,buildingId);
}else if (deviceType.equals("时控")) {
analysisReceiveOrder485.analysisTimeSetOrder485(dataStr,registerAddr,brand,buildingId);
}else if (deviceType.equals("水位开关") && (registerAddr.equals("0018") || registerAddr.equals("0017"))){
analysisReceiveOrder485.analysisRelayOrder485(dataStr,registerAddr,brand,buildingId);
}else if (dataStr.length() == 30 && deviceType.equals("状态检测")) {//五路状态读取,兼容旧版系统
analysisReceiveOrder485.analysisStateOrder485(dataStr,registerAddr,brand,buildingId);
}else if (deviceType.equals("水位开关") && registerAddr.equals("0010")){
analysisReceiveOrder485.analysisPumpStateOrder(dataStr,registerAddr,brand,buildingId); //创新,热泵状态与水位共用一个8路设备
// analysisReceiveOrder485.analysisRelayOrder485(dataStr,registerAddr,brand,buildingId); //华厦
nowDataService.proWaterLevel(dateStr,buildingId); //保存时间点楼栋水位
}else if (deviceType.equals("温度变送器")){
analysisReceiveOrder485.analysisMulTempOrder485(dataStr,registerAddr,brand,buildingId);
}else if (deviceType.equals("热泵状态")){
analysisReceiveOrder485.analysisPumpStateOrder(dataStr,registerAddr,brand,buildingId);
}
}catch (Exception e){
// e.printStackTrace();
Constant.WEB_FLAG=false;//可以采集的状态
if(i==size-1){
Constant.FLAG=false;
}
log.error(deviceManageEntityList.get(i).getDeviceType()+"保存数据库失败!"+i);
}
Thread.sleep(1000);
}else{
Constant.WEB_FLAG=false;//可以采集的状态
if(i==size-1){
Constant.FLAG=false;
}
log.info("-------------串口:"+comName+"不存在!-------------");
}
if(i==size-1){
Constant.FLAG=false;
log.info("-------------一轮采集完,采集标志Constant.Flag="+Constant.FLAG+"-------------");
}
}
}catch (Exception e){
e.printStackTrace();
Constant.WEB_FLAG=false;//可以采集的状态
Constant.FLAG=false;
log.error("-------------串口采集异常!-------------");
}
// }else {
// log.info("串口:"+comName+"不存在!");
// }
}
/**
* 字节数组转16进制字符串
* @param b 字节数组
* @return 16进制字符串
*/
public static String printHexString(byte[] b) {
StringBuilder sbf = new StringBuilder();
for (byte value : b) {
String hex = Integer.toHexString(value & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sbf.append(hex.toUpperCase()).append(" ");
}
return sbf.toString().trim();
}
/**
* 十六进制字符串转byte[]
* @param hex 十六进制字符串
* @return byte[]
*/
public static byte[] hexStr2Byte(String hex) {
if (hex == null) {
return new byte[] {};
}
// 奇数位补0
if (hex.length() % 2 != 0) {
hex = "0" + hex;
}
int length = hex.length();
ByteBuffer buffer = ByteBuffer.allocate(length / 2);
for (int i = 0; i < length; i++) {
String hexStr = hex.charAt(i) + "";
i++;
hexStr += hex.charAt(i);
byte b = (byte) Integer.parseInt(hexStr, 16);
buffer.put(b);
}
return buffer.array();
}
/**
* 16进制转换成为string类型字符串
* @param s 待转换字符串
*/
public static String hexStringToString(String s) {
if (s == null || "".equals(s)) {
return null;
}
s = s.replace(" ", "");
byte[] baKeyword = new byte[s.length() / 2];
for (int i = 0; i < baKeyword.length; i++) {
try {
baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16));
} catch (Exception e) {
e.printStackTrace();
}
}
try {
s = new String(baKeyword, StandardCharsets.UTF_8);
} catch (Exception e1) {
e1.printStackTrace();
}
return s;
}
}

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

Loading…
Cancel
Save