Compare commits
30 Commits
prod_20240
...
dev
Author | SHA1 | Date |
---|---|---|
mh | 6add92e1b6 | 2 weeks ago |
mh | 7ae632a2be | 3 weeks ago |
mh | dadfdafa87 | 3 weeks ago |
mh | 89728921ba | 4 weeks ago |
mh | ba4088e2b8 | 4 weeks ago |
mh | 5344d21ea4 | 4 weeks ago |
v-lijf43 | f555c156c9 | 2 months ago |
mh | f5a1d1b698 | 2 months ago |
mh | 3fe22641d6 | 2 months ago |
mh | 6ccc5be414 | 4 months ago |
mh | 66c0b8f899 | 5 months ago |
mh | c95c8ebc21 | 5 months ago |
mh | b174d79fe5 | 5 months ago |
mh | 2b3b9fbdd5 | 5 months ago |
mh | 659913fd1d | 5 months ago |
mh | b298be7fd9 | 6 months ago |
mh | d93f91037c | 6 months ago |
mh | 6fa9ab3f7e | 6 months ago |
mh | 0023e82d89 | 6 months ago |
mh | 8d77490a9f | 6 months ago |
mh | 6e23904902 | 6 months ago |
mh | f0719ee78d | 6 months ago |
mh | 7fc0d63d6f | 7 months ago |
mh | 9b92196e9c | 7 months ago |
mh | dd2a9e984d | 8 months ago |
mh | 7af983ebad | 8 months ago |
mh | b819375d55 | 8 months ago |
mh | 0127b2122f | 8 months ago |
mh | fc890b53e0 | 8 months ago |
mh | 11fae3d85c | 8 months ago |
117 changed files with 7297 additions and 730 deletions
@ -0,0 +1,207 @@
|
||||
-- 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'; |
||||
|
||||
-- 2024-10-11 添加供水,补水,回水状态 |
||||
ALTER TABLE now_data ADD up_water_state varchar(50) NULL; |
||||
EXEC sp_addextendedproperty 'MS_Description', N'供水状态', 'schema', N'dbo', 'table', N'now_data', 'column', N'up_water_state'; |
||||
ALTER TABLE now_data ADD use_water_state varchar(50) NULL; |
||||
EXEC sp_addextendedproperty 'MS_Description', N'补水状态', 'schema', N'dbo', 'table', N'now_data', 'column', N'use_water_state'; |
||||
ALTER TABLE now_data ADD back_water_state varchar(50) NULL; |
||||
EXEC sp_addextendedproperty 'MS_Description', N'回水状态', 'schema', N'dbo', 'table', N'now_data', 'column', N'back_water_state'; |
||||
|
@ -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> |
@ -0,0 +1,8 @@
|
||||
package com.mh.algorithm.bpnn; |
||||
|
||||
public interface ActivationFunction { |
||||
//计算值
|
||||
double computeValue(double val); |
||||
//计算导数
|
||||
double computeDerivative(double val); |
||||
} |
@ -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; |
||||
} |
||||
} |
@ -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(); |
||||
} |
||||
} |
@ -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; |
||||
} |
||||
} |
@ -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)); |
||||
} |
||||
} |
@ -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; |
||||
|
||||
} |
@ -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; |
||||
} |
||||
|
||||
} |
@ -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; |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
|
||||
} |
@ -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(); |
||||
} |
||||
} |
@ -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; |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
@ -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; |
||||
} |
||||
} |
@ -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"); |
||||
} |
||||
|
||||
} |
@ -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);
|
||||
// }
|
||||
//}
|
@ -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 "";
|
||||
//}
|
||||
|
@ -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();
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
@ -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(); |
||||
} |
||||
|
||||
} |
||||
|
@ -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; |
||||
} |
||||
} |
@ -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; |
||||
} |
||||
} |
@ -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)); |
||||
} |
||||
|
||||
} |
@ -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(); |
||||
} |
||||
|
||||
} |
@ -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; |
||||
|
||||
} |
@ -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; |
||||
|
||||
} |
@ -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; |
||||
|
||||
} |
@ -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 + '\'' + |
||||
'}'; |
||||
} |
||||
} |
@ -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; |
||||
|
||||
} |
@ -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); |
||||
} |
@ -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); |
||||
} |
||||
|
||||
} |
@ -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); |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
@ -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()); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -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); |
||||
} |
@ -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); |
||||
} |
@ -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().toUpperCase(); |
||||
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); |
||||
} |
||||
} |
||||
|
||||
} |
@ -1,281 +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){
|
||||
// Constant.WEB_FLAG=false;//可以采集的状态
|
||||
// if(i==size-1){
|
||||
// Constant.FLAG=false;
|
||||
// }
|
||||
// log.error("发送指令异常==>", e);
|
||||
// }
|
||||
// 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,"离线", buildingName); //监控界面状态表热泵在线状态
|
||||
// }
|
||||
// }
|
||||
// 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,"不运行", buildingName); //监控界面状态表热泵在线状态
|
||||
// }
|
||||
// }
|
||||
// try{
|
||||
// SerialPortSendReceive2.analysisReceiveData(dateStr, deviceType, registerAddr, brand, buildingId, dataStr, analysisReceiveOrder485, nowDataService, buildingName);
|
||||
// }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;
|
||||
// }
|
||||
//}
|
@ -0,0 +1,54 @@
|
||||
package com.mh.user.service; |
||||
|
||||
import com.mh.user.dto.EnergyPreDTO; |
||||
import com.mh.user.dto.EnergyPreEchartDataDTO; |
||||
import com.mh.user.dto.EnergyPreTopDataDTO; |
||||
import com.mh.user.entity.HistoryDataPre; |
||||
|
||||
import java.util.HashMap; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* @author LJF |
||||
* @version 1.0 |
||||
* @project CHWS |
||||
* @description 预测历史数据服务类 |
||||
* @date 2024-05-09 10:02:54 |
||||
*/ |
||||
public interface HistoryDataPreService { |
||||
|
||||
/** |
||||
* 获取训练数据 |
||||
* @param buildingId |
||||
* @throws Exception |
||||
*/ |
||||
void startTrainData(String buildingId) throws Exception; |
||||
|
||||
/** |
||||
* 开始预测数据 |
||||
* @param buildingId |
||||
* @param curDate |
||||
* @throws Exception |
||||
*/ |
||||
void startPredictData(String buildingId, String curDate) throws Exception; |
||||
|
||||
/** |
||||
* 获取每栋楼的数据 |
||||
* @param buildingId |
||||
* @param curDate |
||||
* @return |
||||
*/ |
||||
List<HistoryDataPre> getRecentData(String buildingId, String curDate); |
||||
|
||||
/** |
||||
* 获取预测数据 |
||||
* @param buildingId |
||||
* @param beginDate |
||||
* @param endDate |
||||
* @param type |
||||
* @return |
||||
*/ |
||||
List<HashMap<String, Object>> getEnergyPre(String buildingId, String beginDate, String endDate, String type); |
||||
|
||||
List<EnergyPreTopDataDTO> getTopData(String buildingId, String type); |
||||
} |
@ -0,0 +1,23 @@
|
||||
package com.mh.user.service; |
||||
|
||||
import com.mh.common.page.PageRequest; |
||||
import com.mh.common.page.PageResult; |
||||
import com.mh.user.entity.KnowledgeDataEntity; |
||||
|
||||
/** |
||||
* @author LJF |
||||
* @version 1.0 |
||||
* @project CHWS |
||||
* @description 知识库服务 |
||||
* @date 2024-06-26 14:32:06 |
||||
*/ |
||||
public interface KnowledgeDataService { |
||||
|
||||
void insertKnowledgeData(KnowledgeDataEntity knowledgeData); |
||||
|
||||
PageResult queryKnowledgeData(PageRequest pageRequest); |
||||
|
||||
void updateData(KnowledgeDataEntity knowledgeData); |
||||
|
||||
KnowledgeDataEntity getById(Long id); |
||||
} |
@ -0,0 +1,253 @@
|
||||
package com.mh.user.service.impl; |
||||
|
||||
import com.alibaba.fastjson2.JSON; |
||||
import com.alibaba.fastjson2.JSONArray; |
||||
import com.alibaba.fastjson2.JSONObject; |
||||
import com.alibaba.fastjson2.JSONWriter; |
||||
import com.github.benmanes.caffeine.cache.Cache; |
||||
import com.mh.algorithm.bpnn.BPModel; |
||||
import com.mh.algorithm.bpnn.BPNeuralNetworkFactory; |
||||
import com.mh.algorithm.bpnn.BPParameter; |
||||
import com.mh.algorithm.matrix.Matrix; |
||||
import com.mh.algorithm.utils.CsvInfo; |
||||
import com.mh.algorithm.utils.SerializationUtil; |
||||
import com.mh.common.utils.StringUtils; |
||||
import com.mh.user.dto.EnergyPreDTO; |
||||
import com.mh.user.dto.EnergyPreEchartDataDTO; |
||||
import com.mh.user.dto.EnergyPreTopDataDTO; |
||||
import com.mh.user.entity.HistoryDataPre; |
||||
import com.mh.user.entity.SysParamEntity; |
||||
import com.mh.user.job.GetWeatherInfoJob; |
||||
import com.mh.user.mapper.HistoryDataPreMapper; |
||||
import com.mh.user.service.HistoryDataPreService; |
||||
import com.mh.user.service.SysParamService; |
||||
import com.mh.user.utils.DateUtil; |
||||
import org.springframework.beans.factory.annotation.Qualifier; |
||||
import org.springframework.stereotype.Service; |
||||
import org.springframework.transaction.annotation.Transactional; |
||||
|
||||
import javax.annotation.Resource; |
||||
import java.math.BigDecimal; |
||||
import java.math.RoundingMode; |
||||
import java.time.LocalDate; |
||||
import java.time.format.DateTimeFormatter; |
||||
import java.util.ArrayList; |
||||
import java.util.HashMap; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* @author LJF |
||||
* @version 1.0 |
||||
* @project CHWS |
||||
* @description 预测历史数据服务实现类 |
||||
* @date 2024-05-09 10:03:24 |
||||
*/ |
||||
@Service |
||||
@Transactional(rollbackFor = Exception.class) |
||||
public class HistoryDataPreServiceImpl implements HistoryDataPreService { |
||||
|
||||
@Resource |
||||
private HistoryDataPreMapper historyDataPreMapper; |
||||
|
||||
@Resource |
||||
@Qualifier("caffeineCache") |
||||
private Cache caffeineCache; |
||||
|
||||
@Resource |
||||
private SysParamService sysParamService; |
||||
|
||||
@Resource |
||||
private GetWeatherInfoJob getWeatherInfoJob; |
||||
|
||||
|
||||
public static String[] convert(HistoryDataPre dataPre) { |
||||
// 假设HistoryDataPre有字段如field1, field2, field3等,根据需要进行转换
|
||||
return new String[] { |
||||
String.valueOf(dataPre.getEnvMinTemp()), |
||||
String.valueOf(dataPre.getEnvMaxTemp()), |
||||
String.valueOf(dataPre.getPeopleNum()), |
||||
String.valueOf(dataPre.getWaterValue()), |
||||
String.valueOf(dataPre.getElectValue()), |
||||
String.valueOf(dataPre.getWaterLevel()) |
||||
}; |
||||
} |
||||
|
||||
@Override |
||||
public void startTrainData(String buildingId) throws Exception { |
||||
List<HistoryDataPre> trainData = historyDataPreMapper.getTrainData(buildingId); |
||||
if (trainData == null || trainData.size() == 0) { |
||||
return; |
||||
} |
||||
List<String[]> historyDataPreList = new ArrayList<>(); |
||||
for (HistoryDataPre dataPre : trainData) { |
||||
historyDataPreList.add(convert(dataPre)); |
||||
} |
||||
// 创建训练集矩阵
|
||||
CsvInfo csvInfo = new CsvInfo(); |
||||
csvInfo.setCsvFileList(new ArrayList<>(historyDataPreList)); |
||||
Matrix trainSet = csvInfo.toMatrix(); |
||||
|
||||
// 创建BPNN工厂对象
|
||||
BPNeuralNetworkFactory factory = new BPNeuralNetworkFactory(); |
||||
|
||||
// 创建BP参数对象
|
||||
BPParameter bpParameter = new BPParameter(); |
||||
bpParameter.setInputLayerNeuronCount(3); |
||||
bpParameter.setHiddenLayerNeuronCount(3); |
||||
bpParameter.setOutputLayerNeuronCount(3); |
||||
bpParameter.setPrecision(0.01); |
||||
bpParameter.setMaxTimes(50000); |
||||
|
||||
// 训练BP神经网络
|
||||
BPModel bpModel = factory.trainBP(bpParameter, trainSet); |
||||
|
||||
// 将BPModel序列化到本地
|
||||
SerializationUtil.serialize(bpModel, buildingId+"_pre_data"); |
||||
} |
||||
|
||||
@Override |
||||
public void startPredictData(String buildingId, String curDate) throws Exception { |
||||
// 判断是否存在天气温度数据以及现在的用水量用电量等
|
||||
// int isPre = historyDataPreMapper.selectIsPre(buildingId, curDate);
|
||||
// if (isPre > 0) {
|
||||
// return;
|
||||
// }
|
||||
// 获取当前天气数据
|
||||
SysParamEntity sysParam = sysParamService.selectSysParam(); |
||||
Object weather = caffeineCache.getIfPresent(sysParam.getProArea()); |
||||
if (weather == null) { |
||||
getWeatherInfoJob.getWeatherInfo(); |
||||
weather = caffeineCache.getIfPresent(sysParam.getProArea()); |
||||
} |
||||
String weatherStr = (String) weather; |
||||
JSONObject jsonObject = JSON.parseObject(weatherStr); |
||||
if (null == jsonObject) { |
||||
return; |
||||
} |
||||
String envMinTemp = "16.50"; |
||||
String envMaxTemp = "26.00"; |
||||
JSONArray jsonArray = jsonObject.getJSONArray("forecasts").getJSONObject(0).getJSONArray("casts"); |
||||
for (int i = 0; i < jsonArray.size(); i++) { |
||||
JSONObject jsonObject1 = jsonArray.getJSONObject(i); |
||||
if (jsonObject1.getString("date").equals(curDate)) { |
||||
envMinTemp =jsonObject1.getString("nighttemp"); |
||||
envMaxTemp = jsonObject1.getString("daytemp"); |
||||
break; |
||||
} |
||||
} |
||||
// 获取当前用水量和用电量以及实际平均水位
|
||||
HistoryDataPre curHistoryData = historyDataPreMapper.selectCurData(buildingId, curDate); |
||||
// 插入数据
|
||||
curHistoryData.setEnvMaxTemp(new BigDecimal(envMaxTemp)); |
||||
curHistoryData.setEnvMinTemp(new BigDecimal(envMinTemp)); |
||||
HistoryDataPre historyDataPre = historyDataPreMapper.selectOneData(buildingId, curDate); |
||||
if (historyDataPre == null) { |
||||
historyDataPreMapper.insertData(curHistoryData); |
||||
} |
||||
// 开始预测
|
||||
HistoryDataPre historyDataPre1 = historyDataPreMapper.selectOneData(buildingId, curDate); |
||||
String[] preData = new String[]{ |
||||
historyDataPre1.getEnvMinTemp().toString(), |
||||
historyDataPre1.getEnvMaxTemp().toString(), |
||||
historyDataPre1.getPeopleNum().toString() |
||||
}; |
||||
|
||||
CsvInfo csvInfo = new CsvInfo(); |
||||
ArrayList<String[]> list = new ArrayList<>(); |
||||
list.add(preData); |
||||
csvInfo.setCsvFileList(list); |
||||
Matrix data = csvInfo.toMatrix(); |
||||
// 将BPModel反序列化
|
||||
BPModel bpModel1 = (BPModel) SerializationUtil.deSerialization(buildingId+"_pre_data"); |
||||
// 创建工厂
|
||||
BPNeuralNetworkFactory factory = new BPNeuralNetworkFactory(); |
||||
Matrix result = factory.computeBP(bpModel1, data); |
||||
// 得出预测数据
|
||||
HistoryDataPre preHistoryData = new HistoryDataPre(); |
||||
preHistoryData.setId(historyDataPre1.getId()); |
||||
preHistoryData.setBuildingId(buildingId); |
||||
for (int i = 0; i < result.getMatrixRowCount(); i++) { |
||||
String[] record = new String[result.getMatrixColCount()]; |
||||
for (int j = 0; j < result.getMatrixColCount(); j++) { |
||||
record[j] = String.valueOf(result.getValOfIdx(i, j)); |
||||
} |
||||
// 拼接预测值
|
||||
preHistoryData.setWaterValuePre(evaluateAndReturnBigDecimal(record[0])); |
||||
preHistoryData.setElectValuePre(evaluateAndReturnBigDecimal(record[1])); |
||||
preHistoryData.setWaterLevelPre(evaluateAndReturnBigDecimal(record[2])); |
||||
} |
||||
preHistoryData.setWaterValue(curHistoryData.getWaterValue()); |
||||
preHistoryData.setElectValue(curHistoryData.getElectValue()); |
||||
preHistoryData.setWaterLevel(curHistoryData.getWaterLevel()); |
||||
// 更新预测值
|
||||
historyDataPreMapper.updateById(preHistoryData); |
||||
} |
||||
|
||||
/** |
||||
* 判断输入的字符串转换的BigDecimal是否小于或等于0,返回BigDecimal.ZERO。 |
||||
* 如果小于或等于0,返回输入的BigDecimal;如果大于0,然后返回相应的BigDecimal值。 |
||||
* |
||||
* @param recordValue 记录中的值,用于转换为BigDecimal进行比较 |
||||
* @return 经过判断后的BigDecimal值 |
||||
*/ |
||||
public static BigDecimal evaluateAndReturnBigDecimal(String recordValue) { |
||||
BigDecimal value = new BigDecimal(recordValue); |
||||
if (value.compareTo(BigDecimal.ZERO) >= 0) { |
||||
return value.setScale(2, RoundingMode.HALF_UP); |
||||
} else { |
||||
return BigDecimal.ZERO; |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public List<HistoryDataPre> getRecentData(String buildingId, String curDate) { |
||||
return historyDataPreMapper.getRecentData(buildingId, curDate); |
||||
} |
||||
|
||||
@Override |
||||
public List<HashMap<String, Object>> getEnergyPre(String buildingId, String beginDate, String endDate, String type) { |
||||
if (StringUtils.isBlank(beginDate) || StringUtils.isBlank(endDate)) { |
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); |
||||
// 获取当前日期
|
||||
LocalDate now = LocalDate.now(); |
||||
// 向前推30天
|
||||
LocalDate startDate = now.minusDays(30); |
||||
beginDate = startDate.format(formatter); |
||||
// 结束日期是当前日期
|
||||
endDate = now.format(formatter); |
||||
} |
||||
if (StringUtils.isBlank(buildingId) || StringUtils.isBlank(type)) { |
||||
return null; |
||||
} |
||||
List<EnergyPreEchartDataDTO> energyPre = historyDataPreMapper.getEnergyPre(buildingId, beginDate, endDate, type); |
||||
if (energyPre.size() == 0) { |
||||
return null; |
||||
} |
||||
String[] curDate = energyPre.stream() |
||||
.map(EnergyPreEchartDataDTO::getCurDate) |
||||
.toArray(String[]::new); // 使用stream和map转换每个对象的特定字段为JSON字符串,然后转换成数组
|
||||
String[] curData = energyPre.stream() |
||||
.map(EnergyPreEchartDataDTO::getCurData) |
||||
.toArray(String[]::new); // 使用stream和map转换每个对象的特定字段为JSON字符串,然后转换成数组
|
||||
String[] preData = energyPre.stream() |
||||
.map(EnergyPreEchartDataDTO::getPreData) |
||||
.toArray(String[]::new); // 使用stream和map转换每个对象的特定字段为JSON字符串,然后转换成数组
|
||||
String[] errorData = energyPre.stream() |
||||
.map(EnergyPreEchartDataDTO::getErrorData) |
||||
.toArray(String[]::new); // 使用stream和map转换每个对象的特定字段为JSON字符串,然后转换成数组
|
||||
List<HashMap<String, Object>> resultList = new ArrayList<>(); |
||||
HashMap<String, Object> resultHashMap = new HashMap<>(); |
||||
resultHashMap.put("curDate", curDate); |
||||
resultHashMap.put("curData", curData); |
||||
resultHashMap.put("preData", preData); |
||||
resultHashMap.put("errorData", errorData); |
||||
resultList.add(resultHashMap); |
||||
return resultList; |
||||
} |
||||
|
||||
@Override |
||||
public List<EnergyPreTopDataDTO> getTopData(String buildingId, String type) { |
||||
// 获取顶部数据(昨日,昨日预测,今日预测,昨日偏差值)
|
||||
return historyDataPreMapper.getTopData(buildingId, type); |
||||
} |
||||
} |
@ -0,0 +1,47 @@
|
||||
package com.mh.user.service.impl; |
||||
|
||||
import com.github.pagehelper.PageHelper; |
||||
import com.mh.common.page.ColumnFilter; |
||||
import com.mh.common.page.MybatisPageHelper; |
||||
import com.mh.common.page.PageRequest; |
||||
import com.mh.common.page.PageResult; |
||||
import com.mh.user.entity.KnowledgeDataEntity; |
||||
import com.mh.user.mapper.KnowledgeDataMapper; |
||||
import com.mh.user.service.KnowledgeDataService; |
||||
import org.springframework.stereotype.Service; |
||||
|
||||
import javax.annotation.Resource; |
||||
|
||||
/** |
||||
* @author LJF |
||||
* @version 1.0 |
||||
* @project CHWS |
||||
* @description 知识库服务实现类 |
||||
* @date 2024-06-26 14:33:20 |
||||
*/ |
||||
@Service |
||||
public class KnowledgeDataServiceImpl implements KnowledgeDataService { |
||||
|
||||
@Resource |
||||
private KnowledgeDataMapper knowledgeDataMapper; |
||||
|
||||
@Override |
||||
public void insertKnowledgeData(KnowledgeDataEntity knowledgeData) { |
||||
knowledgeDataMapper.insertKnowledgeData(knowledgeData); |
||||
} |
||||
|
||||
@Override |
||||
public PageResult queryKnowledgeData(PageRequest pageRequest) { |
||||
return MybatisPageHelper.findPage(pageRequest, knowledgeDataMapper); |
||||
} |
||||
|
||||
@Override |
||||
public void updateData(KnowledgeDataEntity knowledgeData) { |
||||
knowledgeDataMapper.updateData(knowledgeData); |
||||
} |
||||
|
||||
@Override |
||||
public KnowledgeDataEntity getById(Long id) { |
||||
return knowledgeDataMapper.getById(id); |
||||
} |
||||
} |
@ -0,0 +1,20 @@
|
||||
package com.mh.user.strategy; |
||||
|
||||
import com.mh.user.entity.DeviceCodeParamEntity; |
||||
|
||||
/** |
||||
* @author LJF |
||||
* @version 1.0 |
||||
* @project CHWS |
||||
* @description 设备操作策略模式 |
||||
* @date 2024-03-15 16:25:43 |
||||
*/ |
||||
public interface DeviceStrategy { |
||||
|
||||
/** |
||||
* 根据读,写方式创建报文 |
||||
*/ |
||||
String createOrders(DeviceCodeParamEntity deviceCodeParamEntity); |
||||
|
||||
String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String dataStr); |
||||
} |
@ -0,0 +1,18 @@
|
||||
package com.mh.user.strategy; |
||||
|
||||
import com.mh.user.constants.DeviceStrategyEnum; |
||||
|
||||
/** |
||||
* @author LJF |
||||
* @version 1.0 |
||||
* @project CHWS |
||||
* @description 策略工厂类 |
||||
* @date 2024-03-18 11:23:38 |
||||
*/ |
||||
public class DeviceStrategyFactory { |
||||
|
||||
public static DeviceStrategy createStrategy(String deviceType) { |
||||
return DeviceStrategyEnum.getDeviceStrategy(deviceType); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,119 @@
|
||||
package com.mh.user.strategy; |
||||
|
||||
import com.mh.common.utils.StringUtils; |
||||
import com.mh.user.entity.DataResultEntity; |
||||
import com.mh.user.entity.DeviceCodeParamEntity; |
||||
import com.mh.user.service.DataResultService; |
||||
import com.mh.user.utils.ExchangeStringUtil; |
||||
import com.mh.user.utils.SpringBeanUtil; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.context.ApplicationContext; |
||||
|
||||
import java.util.Date; |
||||
|
||||
/** |
||||
* @author LJF |
||||
* @version 1.0 |
||||
* @project CHWS |
||||
* @description 电表运行策略 |
||||
* @date 2024-03-18 09:51:17 |
||||
*/ |
||||
@Slf4j |
||||
public class EleMeterStrategy implements DeviceStrategy { |
||||
|
||||
|
||||
// 调用service
|
||||
ApplicationContext context = SpringBeanUtil.getApplicationContext(); |
||||
DataResultService dataResultService = context.getBean(DataResultService.class); |
||||
|
||||
private static class SingletonHolder { |
||||
private static final EleMeterStrategy INSTANCE = new EleMeterStrategy(); |
||||
} |
||||
|
||||
private EleMeterStrategy() { |
||||
// 防止外部直接实例化
|
||||
} |
||||
|
||||
public static EleMeterStrategy getInstance() { |
||||
return EleMeterStrategy.SingletonHolder.INSTANCE; |
||||
} |
||||
|
||||
@Override |
||||
public String createOrders(DeviceCodeParamEntity deviceCodeParamEntity) { |
||||
String str = ""; |
||||
String deviceAddr = deviceCodeParamEntity.getDeviceAddr(); |
||||
if (deviceAddr != null && deviceAddr.length() > 0) { |
||||
try { |
||||
//0代表前面补充0,12代表长度为12,d代表参数为正数型,基表通讯号
|
||||
str = String.format("%012d", Long.parseLong(deviceAddr)); |
||||
//转换位置
|
||||
str = ExchangeStringUtil.changePosition(str); |
||||
//拼接功能码
|
||||
str = "68" + str + "680102"; |
||||
String strData = "1090"; |
||||
//加33操作
|
||||
str = str + ExchangeStringUtil.addThree(strData); |
||||
//检验和
|
||||
String checkSum = ExchangeStringUtil.makeChecksum(str); |
||||
str = "FEFEFE" + str + checkSum + "16"; |
||||
} catch (Exception e) { |
||||
log.error("生成采集电表指令错误==>", e); |
||||
} |
||||
} |
||||
log.info("生成采集电表指令==>" + str); |
||||
return str.toUpperCase(); |
||||
} |
||||
|
||||
@Override |
||||
public String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String dataStr) { |
||||
String data = ""; |
||||
if (dataStr.length() == 36 || dataStr.length() == 40 || dataStr.length() == 44 || dataStr.length() == 50) { |
||||
String checkStr = dataStr.substring(0, dataStr.length() - 4); //减去校验码
|
||||
String checkNum = ExchangeStringUtil.makeChecksum(checkStr); //生成校验码
|
||||
//返回的校验码与重新生成的校验码进行校验
|
||||
if (checkNum.equalsIgnoreCase(dataStr.substring(dataStr.length() - 4, dataStr.length() - 2))) { |
||||
//表号,12位
|
||||
String meterId = checkStr.substring(12, 14) + checkStr.substring(10, 12) + checkStr.substring(8, 10) |
||||
+ checkStr.substring(6, 8) + checkStr.substring(4, 6) + checkStr.substring(2, 4); |
||||
meterId = String.format("%012d", Long.parseLong(meterId)); |
||||
StringBuilder stringBuilder = new StringBuilder(); |
||||
if (dataStr.length() == 36) { |
||||
for (int i = 0; i < 4; i++) { |
||||
String data1 = checkStr.substring(32 - 2 * (i + 1), 32 - 2 * i); |
||||
stringBuilder.append(data1); |
||||
} |
||||
} else { |
||||
for (int i = 0; i < 4; i++) { |
||||
String data1 = checkStr.substring(36 - 2 * (i + 1), 36 - 2 * i); |
||||
stringBuilder.append(data1); |
||||
} |
||||
} |
||||
data = stringBuilder.toString(); |
||||
data = ExchangeStringUtil.cutThree(data); |
||||
// 0 代表前面补充0,4 代表长度为4,d 代表参数为正数型
|
||||
data = String.format("%08d", Long.parseLong(data)); |
||||
data = data.substring(0, 6) + "." + data.substring(6, 8); |
||||
log.info("电表表号:" + meterId + ",电表读数:" + data); |
||||
try { |
||||
DataResultEntity dataResultEntity = new DataResultEntity(); |
||||
dataResultEntity.setDeviceAddr(meterId);//通讯编号
|
||||
dataResultEntity.setDeviceType("电表"); |
||||
dataResultEntity.setBuildingId(buildingId); |
||||
dataResultEntity.setCurValue(Double.parseDouble(data)); //当前读数
|
||||
Date date = new Date(); |
||||
dataResultEntity.setCurDate(date); //当前日期
|
||||
dataResultService.saveDataResult(dataResultEntity); |
||||
log.info("电表数据保存数据库成功! 楼栋名称:" + buildingName); |
||||
} catch (Exception e) { |
||||
log.error("电表数据保存数据库失败!楼栋名称:" + buildingName, e); |
||||
} |
||||
} else { |
||||
log.info("电表报文检验失败: " + dataStr); |
||||
} |
||||
} |
||||
if (!StringUtils.isBlank(data)) { |
||||
data = String.valueOf(Double.valueOf(data)); //00010.76,去除读数前面带0的情况
|
||||
} |
||||
return data; |
||||
} |
||||
} |
@ -0,0 +1,241 @@
|
||||
package com.mh.user.strategy; |
||||
|
||||
import com.alibaba.fastjson2.JSON; |
||||
import com.mh.common.utils.StringUtils; |
||||
import com.mh.user.constants.Constant; |
||||
import com.mh.user.entity.DeviceCodeParamEntity; |
||||
import com.mh.user.service.BuildingService; |
||||
import com.mh.user.service.NowDataService; |
||||
import com.mh.user.service.NowPublicDataService; |
||||
import com.mh.user.utils.ExchangeStringUtil; |
||||
import com.mh.user.utils.SpringBeanUtil; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.context.ApplicationContext; |
||||
|
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* @author LJF |
||||
* @version 1.0 |
||||
* @project CHWS |
||||
* @description 热泵状态 |
||||
* @date 2024-03-18 09:51:17 |
||||
*/ |
||||
@Slf4j |
||||
public class HeatPumpStatusStrategy implements DeviceStrategy { |
||||
|
||||
|
||||
// 调用service
|
||||
ApplicationContext context = SpringBeanUtil.getApplicationContext(); |
||||
NowDataService nowDataService = context.getBean(NowDataService.class); |
||||
NowPublicDataService nowPublicDataService = context.getBean(NowPublicDataService.class); |
||||
BuildingService buildingService = context.getBean(BuildingService.class); |
||||
|
||||
private static class SingletonHolder { |
||||
private static final HeatPumpStatusStrategy INSTANCE = new HeatPumpStatusStrategy(); |
||||
} |
||||
|
||||
private HeatPumpStatusStrategy() { |
||||
// 防止外部直接实例化
|
||||
} |
||||
|
||||
public static HeatPumpStatusStrategy getInstance() { |
||||
return HeatPumpStatusStrategy.SingletonHolder.INSTANCE; |
||||
} |
||||
|
||||
@Override |
||||
public String createOrders(DeviceCodeParamEntity deviceCodeParamEntity) { |
||||
String deviceAddr = deviceCodeParamEntity.getDeviceAddr(); |
||||
String brand = deviceCodeParamEntity.getBrand(); |
||||
String funCode = deviceCodeParamEntity.getFunCode(); |
||||
String registerAddr = deviceCodeParamEntity.getRegisterAddr(); |
||||
String str = ""; |
||||
if (deviceAddr != null && deviceAddr.length() > 0) { |
||||
try { |
||||
if (StringUtils.isBlank(brand) || Constant.BRAND_ZHONG_KAI.equals(brand)) { |
||||
str = ExchangeStringUtil.decToHex(deviceAddr); |
||||
str = ExchangeStringUtil.addZeroForNum(str, 2); |
||||
str = "33" + str + "1700000000"; //旧版继电器
|
||||
// 检验和
|
||||
String checkSum = ExchangeStringUtil.makeChecksum(str); |
||||
str = str + checkSum; |
||||
} else if (Constant.BRAND_YUAN_XIANG.equals(brand)) { |
||||
str = ExchangeStringUtil.decToHex(deviceAddr); |
||||
str = ExchangeStringUtil.addZeroForNum(str, 2); |
||||
str = str + "0300100008"; |
||||
String checkWord = ExchangeStringUtil.getStrCRC16(str); //CRC16校验
|
||||
str = str + checkWord; |
||||
} else if (Constant.BRAND_DING_WEI.equals(brand)) { |
||||
str = String.format("%012d", Long.parseLong(deviceAddr)); |
||||
//转换位置
|
||||
str = ExchangeStringUtil.changePosition(str); //表号
|
||||
String strData = ""; |
||||
str = "68" + str + "680102"; |
||||
strData = "25C0"; //标志
|
||||
// }
|
||||
strData = ExchangeStringUtil.addThree(strData); //加33
|
||||
str = str + strData; |
||||
//检验和
|
||||
String checkSum = ExchangeStringUtil.makeChecksum(str);//校验
|
||||
str = "FEFEFE" + str + checkSum + "16"; |
||||
} |
||||
} catch (Exception e) { |
||||
log.error("生成热泵状态指令出错!" + str, e); |
||||
} |
||||
} |
||||
log.info("生成热泵状态采集指令>>>>" + str); |
||||
return str.toUpperCase(); |
||||
} |
||||
|
||||
@Override |
||||
public String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String receiveData) { |
||||
String result = Constant.FAIL; |
||||
String l1 = ""; |
||||
String l2 = ""; |
||||
String l3 = ""; |
||||
String l4 = ""; |
||||
String l5 = ""; |
||||
String l6 = ""; |
||||
String l7 = ""; |
||||
String l8 = ""; |
||||
String runState = ""; |
||||
String addr = ""; |
||||
Map<String, String> map = new HashMap<String, String>(); |
||||
String checkStr = receiveData.substring(0, receiveData.length() - 4); //检验报文减,去校验码
|
||||
if (StringUtils.isBlank(brand) || brand.equals("顶威")) { |
||||
String checkNum = ExchangeStringUtil.makeChecksum(checkStr); //生成校验码
|
||||
if (checkNum.equalsIgnoreCase(receiveData.substring(receiveData.length() - 4, receiveData.length() - 2))) { |
||||
//表号,12位
|
||||
addr = checkStr.substring(12, 14) + checkStr.substring(10, 12) + checkStr.substring(8, 10) |
||||
+ checkStr.substring(6, 8) + checkStr.substring(4, 6) + checkStr.substring(2, 4); |
||||
addr = addr.replaceAll("^0*", ""); |
||||
String data = checkStr.substring(24, 26); //截取数值
|
||||
data = ExchangeStringUtil.cutThree(data); |
||||
String strStatus = ExchangeStringUtil.hexString2binaryString(data); |
||||
strStatus = String.format("%08d", Long.parseLong(strStatus)); |
||||
if (strStatus.charAt(7) == '1') { |
||||
l1 = "1"; |
||||
} else { |
||||
l1 = "0"; |
||||
} |
||||
if (strStatus.charAt(6) == '1') { |
||||
l2 = "1"; |
||||
} else { |
||||
l2 = "0"; |
||||
} |
||||
if (strStatus.charAt(5) == '1') { |
||||
l3 = "1"; |
||||
} else { |
||||
l3 = "0"; |
||||
} |
||||
if (strStatus.charAt(4) == '1') { |
||||
l4 = "1"; |
||||
} else { |
||||
l4 = "0"; |
||||
} |
||||
if (strStatus.charAt(3) == '1') { |
||||
l5 = "1"; |
||||
} else { |
||||
l5 = "0"; |
||||
} |
||||
if (strStatus.charAt(2) == '1') { |
||||
l6 = "1"; |
||||
} else { |
||||
l6 = "0"; |
||||
} |
||||
if (strStatus.charAt(1) == '1') { |
||||
l7 = "1"; |
||||
} else { |
||||
l7 = "0"; |
||||
} |
||||
if (strStatus.charAt(0) == '1') { |
||||
l8 = "1"; |
||||
} else { |
||||
l8 = "0"; |
||||
} |
||||
} |
||||
} else if (brand.equals("中凯")) { |
||||
addr = ExchangeStringUtil.hexToDec(checkStr.substring(2, 4)); |
||||
l1 = checkStr.substring(4, 6); |
||||
l2 = checkStr.substring(20, 22); |
||||
l3 = checkStr.substring(36, 38); |
||||
l4 = checkStr.substring(52, 54); |
||||
l5 = checkStr.substring(68, 70); |
||||
l6 = checkStr.substring(84, 86); |
||||
l7 = checkStr.substring(100, 102); |
||||
l8 = checkStr.substring(116, 118); |
||||
} else if (brand.equals("远向")) { |
||||
String checkWord = ExchangeStringUtil.getStrCRC16(checkStr); |
||||
if (checkWord.equalsIgnoreCase(receiveData.substring(receiveData.length() - 4))) { |
||||
addr = ExchangeStringUtil.hexToDec(checkStr.substring(0, 2));//地址
|
||||
l1 = checkStr.substring(6, 10); |
||||
l2 = checkStr.substring(10, 14); |
||||
l3 = checkStr.substring(14, 18); |
||||
l4 = checkStr.substring(18, 22); |
||||
l5 = checkStr.substring(22, 26); |
||||
l6 = checkStr.substring(26, 30); |
||||
l7 = checkStr.substring(30, 34); |
||||
l8 = checkStr.substring(34, 38); |
||||
} else { |
||||
log.info("热泵状态报文检验失败: " + receiveData); |
||||
} |
||||
} |
||||
if (l1.equals("12") || l1.equals("0001")) { //正常是0001
|
||||
map.put("1", "运行"); |
||||
} else { |
||||
map.put("1", "不运行"); |
||||
} |
||||
if (l2.equals("12") || l2.equals("0001")) { |
||||
map.put("2", "运行"); |
||||
} else { |
||||
map.put("2", "不运行"); |
||||
} |
||||
if (l3.equals("12") || l3.equals("0001")) { |
||||
map.put("3", "运行"); |
||||
} else { |
||||
map.put("3", "不运行"); |
||||
} |
||||
if (l4.equals("12") || l4.equals("0001")) { |
||||
map.put("4", "运行"); |
||||
} else { |
||||
map.put("4", "不运行"); |
||||
} |
||||
if (l5.equals("12") || l5.equals("0001")) { |
||||
map.put("5", "运行"); |
||||
} else { |
||||
map.put("5", "不运行"); |
||||
} |
||||
if (l6.equals("12") || l6.equals("0001")) { |
||||
map.put("6", "运行"); |
||||
} else { |
||||
map.put("6", "不运行"); |
||||
} |
||||
if (l7.equals("12") || l7.equals("0001")) { |
||||
map.put("7", "运行"); |
||||
} else { |
||||
map.put("7", "不运行"); |
||||
} |
||||
if (l8.equals("12") || l8.equals("0001")) { |
||||
map.put("8", "运行"); |
||||
} else { |
||||
map.put("8", "不运行"); |
||||
} |
||||
int count = buildingService.selectPumpCount(buildingId); //楼栋热泵数
|
||||
if (count > 0) { |
||||
for (Map.Entry<String, String> entry : map.entrySet()) { |
||||
addr = entry.getKey(); //获取Key值作为热泵ID
|
||||
runState = entry.getValue(); |
||||
if (addr != null && Integer.parseInt(addr) <= count) { |
||||
nowDataService.saveNowHistoryData3(addr, "热泵状态", runState, "runState", buildingId); |
||||
nowDataService.proPumpMinutes(buildingId, addr, runState); //计算热泵运行时长
|
||||
nowDataService.proWaterTemp(dateStr, buildingId, addr); //保存时间点温度
|
||||
log.info("计算热泵运行时长,楼栋名称:" + buildingName + ",热泵编号:" + addr + ",状态:" + runState); |
||||
} |
||||
} |
||||
log.info("热泵状态号:" + addr + ",保存数据库成功!楼栋名称:" + buildingName); |
||||
result = JSON.toJSONString(map); //map转json字符串
|
||||
} |
||||
return result; |
||||
} |
||||
} |
@ -0,0 +1,542 @@
|
||||
package com.mh.user.strategy; |
||||
|
||||
import com.mh.common.utils.StringUtils; |
||||
import com.mh.user.constants.Constant; |
||||
import com.mh.user.entity.DeviceCodeParamEntity; |
||||
import com.mh.user.entity.NowPublicDataEntity; |
||||
import com.mh.user.service.*; |
||||
import com.mh.user.utils.ExchangeStringUtil; |
||||
import com.mh.user.utils.SpringBeanUtil; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.context.ApplicationContext; |
||||
|
||||
import java.math.BigDecimal; |
||||
|
||||
/** |
||||
* @author LJF |
||||
* @version 1.0 |
||||
* @project CHWS |
||||
* @description 热泵策略 |
||||
* @date 2024-03-18 09:51:17 |
||||
*/ |
||||
@Slf4j |
||||
public class HeatPumpStrategy implements DeviceStrategy { |
||||
|
||||
|
||||
// 调用service
|
||||
ApplicationContext context = SpringBeanUtil.getApplicationContext(); |
||||
NowDataService nowDataService = context.getBean(NowDataService.class); |
||||
NowPublicDataService nowPublicDataService = context.getBean(NowPublicDataService.class); |
||||
PumpSetService pumpSetService = context.getBean(PumpSetService.class); |
||||
DeviceInstallService deviceInstallService = context.getBean(DeviceInstallService.class); |
||||
|
||||
private static class SingletonHolder { |
||||
private static final HeatPumpStrategy INSTANCE = new HeatPumpStrategy(); |
||||
} |
||||
|
||||
private HeatPumpStrategy() { |
||||
// 防止外部直接实例化
|
||||
} |
||||
|
||||
public static HeatPumpStrategy getInstance() { |
||||
return HeatPumpStrategy.SingletonHolder.INSTANCE; |
||||
} |
||||
|
||||
@Override |
||||
public String createOrders(DeviceCodeParamEntity deviceCodeParamEntity) { |
||||
String deviceAddr = deviceCodeParamEntity.getDeviceAddr(); |
||||
String brand = deviceCodeParamEntity.getBrand(); |
||||
String funCode = deviceCodeParamEntity.getFunCode(); |
||||
String registerAddr = deviceCodeParamEntity.getRegisterAddr(); |
||||
String dataValue = deviceCodeParamEntity.getDataValue(); |
||||
String str = ""; |
||||
String param = ""; |
||||
if (deviceAddr != null && deviceAddr.length() > 0) { |
||||
try { |
||||
// 0代表前面补充0,2代表长度为2,d代表参数为正数型
|
||||
str = ExchangeStringUtil.decToHex(deviceAddr); |
||||
str = ExchangeStringUtil.addZeroForNum(str, 2); |
||||
if (StringUtils.isBlank(brand) || Constant.BRAND_MEI_DI.equals(brand)) { |
||||
if (StringUtils.isBlank(funCode) || funCode.equals("03")) { |
||||
if (StringUtils.isBlank(registerAddr) || registerAddr.equalsIgnoreCase("0641")) { // 运行状态
|
||||
str = str + "0306410001"; |
||||
param = "运行状态"; |
||||
} else if (registerAddr.equalsIgnoreCase("0007")) { // 水温
|
||||
str = str + "0300070001"; |
||||
param = "实际温度"; |
||||
} else if (registerAddr.equalsIgnoreCase("000B")) { // 故障状态,100*N+11
|
||||
str = str + "03000B0001"; |
||||
param = "故障状态"; |
||||
} else if (registerAddr.equalsIgnoreCase("0642")) { // 读温度设定
|
||||
str = str + "0306420001"; |
||||
param = "设定温度"; |
||||
} else if (registerAddr.equalsIgnoreCase("0656")) { //读时段1
|
||||
str = str + "0306560004"; |
||||
param = "时段1"; |
||||
} else if (registerAddr.equalsIgnoreCase("065A")) { //读时段2
|
||||
str = str + "03065A0004"; |
||||
param = "时段2"; |
||||
} |
||||
} else {//10
|
||||
if (StringUtils.isBlank(registerAddr) || registerAddr.equalsIgnoreCase("0642")) {//温度设定,写
|
||||
str = str + "100642000102" + ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.decToHex(String.valueOf(dataValue)), 4); //写,待测试
|
||||
} else { |
||||
if (dataValue.length() == 8) { |
||||
String strData = "00" + dataValue.substring(0, 2) + "00" + dataValue.substring(2, 4) + "00" + dataValue.substring(4, 6) + "00" + dataValue.substring(6, 8); |
||||
if (registerAddr.equalsIgnoreCase("0656")) {//时段1
|
||||
str = str + "100656000408" + strData; //写
|
||||
} else if (registerAddr.equalsIgnoreCase("065A")) {//时段2
|
||||
str = str + "10065A000408" + strData; //写
|
||||
} |
||||
} |
||||
} |
||||
} |
||||
} else if (Constant.BRAND_MEI_DI_TWO.equals(brand)) { |
||||
if (StringUtils.isBlank(funCode) || funCode.equals("03")) { |
||||
if (registerAddr == null || registerAddr.equals("") || registerAddr.equalsIgnoreCase("0BBD")) { // 运行状态
|
||||
str = str + "030BBD0001"; |
||||
param = "运行状态"; |
||||
} else if (registerAddr.equalsIgnoreCase("0064")) { // 水温
|
||||
str = str + "0300640001"; |
||||
param = "实际温度"; |
||||
} else if (registerAddr.equalsIgnoreCase("0BBB")) { // 故障状态
|
||||
str = str + "030BBB0001"; |
||||
param = "故障状态"; |
||||
} else if (registerAddr.equalsIgnoreCase("0003")) { // 读温度设定
|
||||
str = str + "0300030001"; |
||||
param = "设定温度"; |
||||
} |
||||
} else {//06
|
||||
if (StringUtils.isBlank(registerAddr) || registerAddr.equalsIgnoreCase("0003")) {//温度设定,写
|
||||
str = str + "060003" + ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.decToHex(String.valueOf(dataValue)), 4); //写,待测试
|
||||
} else if (registerAddr.equals("0000")) {//开关机
|
||||
if (dataValue.equals("0000")) { |
||||
str = str + "0600000000"; //关机
|
||||
} else { |
||||
str = str + "0600000003"; //制热水,开机
|
||||
} |
||||
} |
||||
} |
||||
} else if (Constant.BRAND_RUI_XING.equals(brand)) { |
||||
if (StringUtils.isBlank(funCode) || funCode.equals("03")) { |
||||
if (StringUtils.isBlank(registerAddr) || registerAddr.equalsIgnoreCase("0001")) { // 运行状态
|
||||
str = str + "0300010001"; |
||||
param = "运行状态"; |
||||
} else if (registerAddr.equalsIgnoreCase("0046")) { // 水温
|
||||
str = str + "0300460001"; |
||||
param = "实际温度"; |
||||
} else if (registerAddr.equalsIgnoreCase("0050")) { // 故障状态,100*N+11
|
||||
str = str + "0300500001"; |
||||
param = "故障状态"; |
||||
} else if (registerAddr.equalsIgnoreCase("000A")) { // 读温度设定
|
||||
str = str + "03000A0001"; |
||||
param = "设定温度"; |
||||
} else if (registerAddr.equalsIgnoreCase("0028")) { //读时段1
|
||||
str = str + "0300280004"; |
||||
param = "时段1"; |
||||
} else if (registerAddr.equalsIgnoreCase("002C")) { //读时段2
|
||||
str = str + "03002C0004"; |
||||
param = "时段2"; |
||||
} |
||||
} else if ("06".equals(funCode)) { |
||||
str = str + funCode + registerAddr;// 定时开机开关机
|
||||
if ("0023".equals(registerAddr)) { |
||||
param = "时段1"; |
||||
} else { |
||||
param = "时段2"; |
||||
} |
||||
} else {//10
|
||||
if (StringUtils.isBlank(registerAddr) || registerAddr.equalsIgnoreCase("000A")) {//温度设定,写
|
||||
str = str + "10000A000102" + ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.decToHex(String.valueOf(dataValue)), 4); //写,待测试
|
||||
} else if (registerAddr.equalsIgnoreCase("0028") || registerAddr.equalsIgnoreCase("002C")) {//时段1
|
||||
if (dataValue.length() == 8) { |
||||
String strData = "00" + ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.IntToHex(Integer.parseInt(dataValue.substring(0, 2))),2) |
||||
+ "00" + ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.IntToHex(Integer.parseInt(dataValue.substring(2, 4))),2) |
||||
+ "00" + ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.IntToHex(Integer.parseInt(dataValue.substring(4, 6))),2) |
||||
+ "00" + ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.IntToHex(Integer.parseInt(dataValue.substring(6, 8))),2); |
||||
str = str + "10"+registerAddr+"000408" + strData; //写
|
||||
} |
||||
} |
||||
} |
||||
} else if (Constant.BRAND_HAI_ER.equals(brand)) { |
||||
if (StringUtils.isBlank(funCode) || funCode.equals("03")) { |
||||
if (StringUtils.isBlank(registerAddr) |
||||
|| registerAddr.equalsIgnoreCase(ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.decToHex("20001"),4))) { // 运行状态
|
||||
str = str + "03"+registerAddr+"0001"; |
||||
param = "运行状态"; |
||||
} else if (registerAddr.equalsIgnoreCase(ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.decToHex("20026"),4))) { // 水温
|
||||
str = str + "03"+registerAddr+"0001"; |
||||
param = "实际温度"; |
||||
} else if (registerAddr.equalsIgnoreCase(ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.decToHex("20041"),4))) { // 故障状态,100*N+11
|
||||
str = str + "03"+registerAddr+"0001"; |
||||
param = "故障状态"; |
||||
} else if (registerAddr.equalsIgnoreCase(ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.decToHex("20003"),4))) { // 读温度设定
|
||||
str = str + "03"+registerAddr+"0001"; |
||||
param = "设定温度"; |
||||
} |
||||
} else if ("06".equals(funCode)) { |
||||
if (registerAddr.equalsIgnoreCase(ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.decToHex("20003"), 4))) { |
||||
dataValue = (new BigDecimal(dataValue)).multiply(new BigDecimal("10")).toString(); |
||||
} |
||||
String dataStr = ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.decToHex(String.valueOf(dataValue)), 4); |
||||
str = str + funCode + registerAddr + dataStr; |
||||
} |
||||
} |
||||
String checkWord = ExchangeStringUtil.getStrCRC16(str); //CRC16校验
|
||||
str = str + checkWord; |
||||
} catch (Exception e) { |
||||
log.info("热泵" + param + "指令>>>>异常" + str, e); |
||||
} |
||||
} |
||||
log.info("热泵" + param + "指令>>>>" + str); |
||||
return str.toUpperCase(); |
||||
} |
||||
|
||||
@Override |
||||
public String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String dataStr) { |
||||
String checkStr = dataStr.substring(0, dataStr.length() - 4);//检验报文
|
||||
String checkWord = ExchangeStringUtil.getStrCRC16(checkStr);//生成校验码
|
||||
String sValue = null; |
||||
StringBuffer dataType = new StringBuffer(); |
||||
String rtData = Constant.FAIL; |
||||
if (!checkWord.equalsIgnoreCase(dataStr.substring(dataStr.length() - 4))) { |
||||
log.info("热泵报文检验失败: " + dataStr); |
||||
return Constant.FAIL; |
||||
} |
||||
String addr = ExchangeStringUtil.hexToDec(checkStr.substring(0, 2));//地址
|
||||
String data = ""; |
||||
if (StringUtils.isBlank(brand) || Constant.BRAND_MEI_DI.equals(brand)) { |
||||
if (checkStr.substring(2, 4).equalsIgnoreCase("03")) {//读
|
||||
rtData = getMeiDi(registerAddr, buildingId, buildingName, checkStr, sValue, addr, dataType); |
||||
} else if (checkStr.substring(2, 4).equalsIgnoreCase("10")) { |
||||
log.info("时间: " + dateStr + ",热泵ID: " + addr + ",操作成功! "); |
||||
return Constant.SUCCESS; |
||||
} |
||||
} else if (Constant.BRAND_MEI_DI_TWO.equals(brand)) { |
||||
if (checkStr.substring(2, 4).equalsIgnoreCase("03")) {// 读
|
||||
rtData = getMeiDiTwo(registerAddr, buildingId, buildingName, checkStr, sValue, addr, dataType); |
||||
} else if (checkStr.substring(2, 4).equalsIgnoreCase("06")) { |
||||
log.info("时间: " + dateStr + ",热泵ID: " + addr + ",操作成功! "); |
||||
return Constant.SUCCESS; |
||||
} |
||||
} else if (Constant.BRAND_RUI_XING.equals(brand)) { |
||||
rtData = getRuiXing(dateStr, registerAddr, buildingId, buildingName, checkStr, sValue, addr, dataType); |
||||
} else if (Constant.BRAND_HAI_ER.equals(brand)) { |
||||
rtData = getHaiEr(dateStr, registerAddr, buildingId, buildingName, checkStr, sValue, addr, dataType); |
||||
} |
||||
if (!StringUtils.isBlank(rtData)) { |
||||
nowDataService.saveNowHistoryData(addr, "热泵", rtData, dataType.toString(), buildingId); |
||||
log.info("时间: " + dateStr + "热泵ID:" + addr + ",数据: " + rtData + ",保存数据库成功!楼栋名称:" + buildingName); |
||||
} |
||||
nowDataService.proWaterTemp(dateStr, buildingId, addr); //保存楼栋时间点温度变化
|
||||
log.info("----------------保存楼栋时间点温度变化值!----------------"); |
||||
return rtData; |
||||
} |
||||
|
||||
private String getHaiEr(String dateStr, String registerAddr, String buildingId, String buildingName, String checkStr, String sValue, String addr, StringBuffer stringBuffer) { |
||||
String data; |
||||
stringBuffer.setLength(0); |
||||
String dataType = ""; |
||||
if (checkStr.substring(2, 4).equalsIgnoreCase("03")) {//读
|
||||
if (registerAddr.equalsIgnoreCase(ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.decToHex("20001"), 4))) { //运行状态
|
||||
dataType = "runState"; |
||||
data = checkStr.substring(8, 10); |
||||
if (data.equalsIgnoreCase("00")) { |
||||
sValue = "不运行"; //关机模式
|
||||
} else if (data.equalsIgnoreCase("01")) { |
||||
sValue = "运行"; // 开机模式
|
||||
} |
||||
//计算热泵运行时间,按分钟
|
||||
nowDataService.proPumpMinutes(buildingId, addr, sValue); |
||||
log.info("计算热泵运行时长,楼栋名称:" + buildingName + ",热泵编号:" + addr + ",状态:" + sValue); |
||||
} else if (registerAddr.equalsIgnoreCase(ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.decToHex("20003"), 4)) |
||||
|| registerAddr.equalsIgnoreCase(ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.decToHex("20026"), 4)) ) { |
||||
//20003设定温度,20026水箱水温
|
||||
if (registerAddr.equalsIgnoreCase(ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.decToHex("20003"), 4))) { |
||||
dataType = "tempSet"; |
||||
} else { |
||||
dataType = "waterTemp"; |
||||
} |
||||
//读数
|
||||
sValue = ExchangeStringUtil.hexToDec(checkStr.substring(6, 10)); |
||||
sValue = String.valueOf(Double.parseDouble(sValue)/10); |
||||
if (dataType.equals("waterTemp")) { |
||||
String avgTemp = nowDataService.selectAve(buildingId); |
||||
NowPublicDataEntity publicData = new NowPublicDataEntity(); |
||||
publicData.setBuildingId(buildingId); |
||||
publicData.setUseWaterTemp(avgTemp); |
||||
publicData.setBackWaterTemp(avgTemp); |
||||
String pumpId = nowDataService.selectMinPumpId(buildingId); |
||||
log.info("---------------addr:" + addr + ",pumpId:" + pumpId + " ---------------"); |
||||
if (addr.equals(pumpId)) { //取ID最小的热泵为单箱温度
|
||||
publicData.setSingleTemp(sValue); |
||||
log.info("---------------单箱温度:" + sValue + "---------------"); |
||||
} |
||||
nowPublicDataService.saveNowHistoryPublicData(publicData); |
||||
log.info("楼栋名称:" + buildingName + ",热泵编号:" + addr); |
||||
} else if (dataType.equals("tempSet")) { |
||||
pumpSetService.updatePumpSetTemp(sValue, buildingId, addr); //更新设定温度
|
||||
} |
||||
} else if (registerAddr.equalsIgnoreCase(ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.decToHex("20041"), 4))) { //故障状态
|
||||
dataType = "isFault"; |
||||
String sData = ExchangeStringUtil.hexString2binaryString(checkStr.substring(8, 10)); |
||||
sData = ExchangeStringUtil.addZeroForNum(sData, 8); |
||||
if (sData.substring(7, 8).equalsIgnoreCase("0")) { |
||||
sValue = "无故障"; |
||||
deviceInstallService.updateDeviceFault("0", addr, "热泵"); |
||||
} else if (sData.substring(7, 8).equalsIgnoreCase("1")) { |
||||
sValue = "有故障"; |
||||
deviceInstallService.updateDeviceFault("1", addr, "热泵"); |
||||
} |
||||
} |
||||
} else if (checkStr.substring(2, 4).equalsIgnoreCase("06")) { |
||||
if (registerAddr.equalsIgnoreCase("0001")) { //运行状态
|
||||
dataType = "runState"; |
||||
data = checkStr.substring(10, 12); |
||||
if (data.equalsIgnoreCase("00")) { |
||||
sValue = "不运行"; //开机模式
|
||||
} else if (data.equalsIgnoreCase("01")) { |
||||
sValue = "运行"; // 开机模式
|
||||
} |
||||
//计算热泵运行时间,按分钟
|
||||
nowDataService.proPumpMinutes(buildingId, addr, sValue); |
||||
log.info("计算热泵运行时长,楼栋名称:" + buildingName + ",热泵编号:" + addr + ",状态:" + sValue); |
||||
} |
||||
} else if (checkStr.substring(2, 4).equalsIgnoreCase("10")) { |
||||
log.info("时间: " + dateStr + ",热泵ID: " + addr + ",操作成功! "); |
||||
sValue = Constant.SUCCESS; |
||||
} |
||||
stringBuffer.append(dataType); |
||||
return sValue; |
||||
} |
||||
|
||||
private String getRuiXing(String dateStr, String registerAddr, String buildingId, String buildingName, String checkStr, String sValue, String addr, StringBuffer stringBuffer) { |
||||
String data; |
||||
String dataType = ""; |
||||
stringBuffer.setLength(0); |
||||
if (checkStr.substring(2, 4).equalsIgnoreCase("03")) {//读
|
||||
if (registerAddr.equalsIgnoreCase("0001")) { //运行状态
|
||||
dataType = "runState"; |
||||
data = checkStr.substring(8, 10); |
||||
if (data.equalsIgnoreCase("00")) { |
||||
sValue = "不运行"; //关机模式
|
||||
} else if (data.equalsIgnoreCase("01")) { |
||||
sValue = "运行"; //制热模式
|
||||
} |
||||
//计算热泵运行时间,按分钟
|
||||
nowDataService.proPumpMinutes(buildingId, addr, sValue); |
||||
log.info("计算热泵运行时长,楼栋名称:" + buildingName + ",热泵编号:" + addr + ",状态:" + sValue); |
||||
} else if (registerAddr.equalsIgnoreCase("000A") || registerAddr.equalsIgnoreCase("0046")) { |
||||
//000A设定温度,0046水箱水温
|
||||
if (registerAddr.equalsIgnoreCase("000A")) { |
||||
dataType = "tempSet"; |
||||
} else { |
||||
dataType = "waterTemp"; |
||||
} |
||||
//读数
|
||||
sValue = ExchangeStringUtil.hexToDec(checkStr.substring(6, 10)); |
||||
if (dataType.equals("waterTemp")) { |
||||
sValue = String.valueOf(Double.parseDouble(sValue)/10); |
||||
String avgTemp = nowDataService.selectAve(buildingId); |
||||
NowPublicDataEntity publicData = new NowPublicDataEntity(); |
||||
publicData.setBuildingId(buildingId); |
||||
// 供水温度
|
||||
publicData.setUseWaterTemp(avgTemp); |
||||
// 回水温度
|
||||
publicData.setBackWaterTemp(avgTemp); |
||||
String pumpId = nowDataService.selectMinPumpId(buildingId); |
||||
log.info("---------------addr:" + addr + ",pumpId:" + pumpId + " ---------------"); |
||||
if (addr.equals(pumpId)) { //取ID最小的热泵为单箱温度
|
||||
publicData.setSingleTemp(sValue); |
||||
log.info("---------------单箱温度:" + sValue + "---------------"); |
||||
} |
||||
nowPublicDataService.saveNowHistoryPublicData(publicData); |
||||
log.info("楼栋名称:" + buildingName + ",热泵编号:" + addr); |
||||
} else if (dataType.equals("tempSet")) { |
||||
pumpSetService.updatePumpSetTemp(sValue, buildingId, addr); //更新设定温度
|
||||
} |
||||
} else if (registerAddr.equalsIgnoreCase("0050")) { //故障状态
|
||||
dataType = "isFault"; |
||||
String sData = ExchangeStringUtil.hexString2binaryString(checkStr.substring(8, 10)); |
||||
sData = ExchangeStringUtil.addZeroForNum(sData, 8); |
||||
if (sData.substring(7, 8).equalsIgnoreCase("0")) { |
||||
sValue = "无故障"; |
||||
deviceInstallService.updateDeviceFault("0", addr, "热泵"); |
||||
} else if (sData.substring(7, 8).equalsIgnoreCase("1")) { |
||||
sValue = "有故障"; |
||||
deviceInstallService.updateDeviceFault("1", addr, "热泵"); |
||||
} |
||||
} else if (registerAddr.equalsIgnoreCase("0028") |
||||
|| registerAddr.equalsIgnoreCase("002C") |
||||
|| registerAddr.equalsIgnoreCase("0030")) { //读定时设置值
|
||||
// 01 03 08 0003 0000 0016 0000 4713
|
||||
String startTime = ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.hexToDec(checkStr.substring(6, 10)), 2) |
||||
+ ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.hexToDec(checkStr.substring(10, 14)), 2); |
||||
String closetTime = ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.hexToDec(checkStr.substring(14, 18)), 2) |
||||
+ ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.hexToDec(checkStr.substring(18, 22)), 2); |
||||
sValue = startTime + closetTime; |
||||
} |
||||
} else if (checkStr.substring(2, 4).equalsIgnoreCase("06")) { |
||||
if (registerAddr.equalsIgnoreCase("0001")) { //运行状态
|
||||
dataType = "runState"; |
||||
data = checkStr.substring(10, 12); |
||||
if (data.equalsIgnoreCase("00")) { |
||||
sValue = "不运行"; //关机模式
|
||||
} else if (data.equalsIgnoreCase("01")) { |
||||
sValue = "运行"; //制热模式
|
||||
} |
||||
//计算热泵运行时间,按分钟
|
||||
nowDataService.proPumpMinutes(buildingId, addr, sValue); |
||||
log.info("计算热泵运行时长,楼栋名称:" + buildingName + ",热泵编号:" + addr + ",状态:" + sValue); |
||||
} else { |
||||
log.info("时间: " + dateStr + ",热泵ID: " + addr + ",操作成功! "); |
||||
sValue = Constant.SUCCESS; |
||||
} |
||||
} |
||||
stringBuffer.append(dataType); |
||||
return sValue; |
||||
} |
||||
|
||||
private String getMeiDi(String registerAddr, String buildingId, String buildingName, String checkStr, String sValue, String addr, StringBuffer stringBuffer) { |
||||
String data; |
||||
String dataType = ""; |
||||
stringBuffer.setLength(0); |
||||
if (registerAddr.equalsIgnoreCase("0641")) { //运行状态
|
||||
dataType = "runState"; |
||||
data = checkStr.substring(8, 10); |
||||
log.info("------------美的热泵状态值-----------" + data); |
||||
if (data.equalsIgnoreCase("08")) { |
||||
sValue = "不运行"; //关机模式
|
||||
} else if (data.equalsIgnoreCase("01")) { |
||||
sValue = "运行"; //制冷模式
|
||||
} else if (data.equalsIgnoreCase("02")) { |
||||
sValue = "运行"; //制热模式
|
||||
} else if (data.equalsIgnoreCase("04")) { |
||||
sValue = "运行"; //水泵模式
|
||||
} else if (data.equalsIgnoreCase("10")) { |
||||
sValue = "运行"; //制热水模式
|
||||
} |
||||
//计算热泵运行时间,按分钟
|
||||
nowDataService.proPumpMinutes(buildingId, addr, sValue); |
||||
log.info("计算热泵运行时长,楼栋名称:" + buildingName + ",热泵编号:" + addr + ",状态:" + sValue); |
||||
} else if (registerAddr.equalsIgnoreCase("0642") || registerAddr.equalsIgnoreCase("0007")) { |
||||
//0642设定温度,0007水箱水温
|
||||
if (registerAddr.equalsIgnoreCase("0642")) { |
||||
dataType = "tempSet"; |
||||
} else { |
||||
dataType = "waterTemp"; |
||||
} |
||||
//读数
|
||||
sValue = ExchangeStringUtil.hexToDec(checkStr.substring(6, 10)); |
||||
if (dataType.equals("waterTemp")) { |
||||
String avgTemp = nowDataService.selectAve(buildingId); |
||||
NowPublicDataEntity publicData = new NowPublicDataEntity(); |
||||
publicData.setBuildingId(buildingId); |
||||
publicData.setUseWaterTemp(avgTemp); |
||||
publicData.setBackWaterTemp(avgTemp); |
||||
String pumpId = nowDataService.selectMinPumpId(buildingId); |
||||
if (addr.equals(pumpId)) { //取ID最小的热泵为单箱温度
|
||||
publicData.setSingleTemp(sValue); |
||||
log.info("---------------单箱温度:" + sValue + "---------------"); |
||||
} |
||||
nowPublicDataService.saveNowHistoryPublicData(publicData); |
||||
log.info("楼栋名称:" + buildingName + ",热泵编号:" + addr); |
||||
} else if (dataType.equals("tempSet")) { |
||||
pumpSetService.updatePumpSetTemp(sValue, buildingId, addr); //更新设定温度
|
||||
} |
||||
} else if (registerAddr.equalsIgnoreCase("000B")) { //故障状态
|
||||
dataType = "isFault"; |
||||
String sData = ExchangeStringUtil.hexString2binaryString(checkStr.substring(8, 10)); |
||||
sData = ExchangeStringUtil.addZeroForNum(sData, 8); |
||||
if (sData.substring(7, 8).equalsIgnoreCase("0")) { |
||||
sValue = "无故障"; |
||||
deviceInstallService.updateDeviceFault("0", addr, "热泵"); |
||||
} else if (sData.substring(7, 8).equalsIgnoreCase("1")) { |
||||
sValue = "有故障"; |
||||
deviceInstallService.updateDeviceFault("1", addr, "热泵"); |
||||
} |
||||
} else if (registerAddr.equalsIgnoreCase("0656") |
||||
|| registerAddr.equalsIgnoreCase("065A") |
||||
|| registerAddr.equalsIgnoreCase("065E")) { //读定时设置值
|
||||
String startTime = checkStr.substring(8, 10) + checkStr.substring(12, 14); |
||||
String closetTime = checkStr.substring(16, 18) + checkStr.substring(20, 22); |
||||
sValue = startTime + closetTime; |
||||
} |
||||
stringBuffer.append(dataType); |
||||
return sValue; |
||||
} |
||||
|
||||
private String getMeiDiTwo(String registerAddr, String buildingId, String buildingName, String checkStr, String sValue, String addr, StringBuffer stringBuffer) { |
||||
String data; |
||||
String dataType = ""; |
||||
stringBuffer.setLength(0); |
||||
if (registerAddr.equalsIgnoreCase("0BBD")) { //运行状态
|
||||
dataType = "runState"; |
||||
data = ExchangeStringUtil.hexString2binaryString(checkStr.substring(8, 10)); |
||||
data = ExchangeStringUtil.addZeroForNum(data, 8);//二进制数,补够8位
|
||||
data = data.substring(4, 8); //截取后四位
|
||||
log.info("------------美的2热泵状态值-----------" + data); |
||||
if (data.equalsIgnoreCase("0000")) { //0
|
||||
sValue = "不运行"; //关机
|
||||
} else if (data.equalsIgnoreCase("0001")) {//1
|
||||
sValue = "运行"; //水泵
|
||||
} else if (data.equalsIgnoreCase("0010")) {//2
|
||||
sValue = "运行"; //制冷
|
||||
} else if (data.equalsIgnoreCase("0011")) {//3
|
||||
sValue = "运行"; //制热
|
||||
} else if (data.equalsIgnoreCase("0100")) {//4
|
||||
sValue = "运行"; //热水
|
||||
} else if (data.equalsIgnoreCase("0101")) {//5
|
||||
sValue = "运行"; //采暖
|
||||
} else if (data.equalsIgnoreCase("0110")) {//6
|
||||
sValue = "运行"; //电热模式
|
||||
} |
||||
//计算热泵运行时间,按分钟
|
||||
nowDataService.proPumpMinutes(buildingId, addr, sValue); |
||||
log.info("计算热泵运行时长,楼栋名称:" + buildingName + ",热泵编号:" + addr + ",状态:" + sValue); |
||||
} else if (registerAddr.equalsIgnoreCase("0003") || registerAddr.equalsIgnoreCase("0064")) { |
||||
//0003设定温度,0064水箱水温
|
||||
if (registerAddr.equalsIgnoreCase("0003")) { |
||||
dataType = "tempSet"; |
||||
} else { |
||||
dataType = "waterTemp"; |
||||
} |
||||
//读数
|
||||
sValue = ExchangeStringUtil.hexToDec(checkStr.substring(6, 10)); |
||||
if (dataType.equals("waterTemp")) { |
||||
String avgTemp = nowDataService.selectAve(buildingId); |
||||
NowPublicDataEntity publicData = new NowPublicDataEntity(); |
||||
publicData.setBuildingId(buildingId); |
||||
publicData.setUseWaterTemp(avgTemp); |
||||
publicData.setBackWaterTemp(avgTemp); |
||||
String pumpId = nowDataService.selectMinPumpId(buildingId); |
||||
log.info("---------------addr:" + addr + ",pumpId:" + pumpId + " ---------------"); |
||||
if (addr.equals(pumpId)) { //取ID最小的热泵为单箱温度
|
||||
publicData.setSingleTemp(sValue); |
||||
log.info("---------------单箱温度:" + sValue + "---------------"); |
||||
} |
||||
nowPublicDataService.saveNowHistoryPublicData(publicData); |
||||
log.info("楼栋名称:" + buildingName + ",热泵编号:" + addr); |
||||
} else if (dataType.equals("tempSet")) { |
||||
pumpSetService.updatePumpSetTemp(sValue, buildingId, addr); //更新设定温度
|
||||
} |
||||
} else if (registerAddr.equalsIgnoreCase("0BBB")) { //故障状态
|
||||
dataType = "isFault"; |
||||
String sData = ExchangeStringUtil.hexString2binaryString(checkStr.substring(8, 10)); |
||||
sData = ExchangeStringUtil.addZeroForNum(sData, 8); |
||||
if (sData.substring(7, 8).equalsIgnoreCase("0")) { |
||||
sValue = "无故障"; |
||||
} else if (sData.substring(7, 8).equalsIgnoreCase("1")) { |
||||
sValue = "有故障"; |
||||
} |
||||
} else if (registerAddr.equalsIgnoreCase("0656") |
||||
|| registerAddr.equalsIgnoreCase("065A") |
||||
|| registerAddr.equalsIgnoreCase("065E")) { //定时设置值
|
||||
String startTime = ExchangeStringUtil.hexToDec(checkStr.substring(8, 10)) + ExchangeStringUtil.hexToDec(checkStr.substring(12, 14)); |
||||
String closetTime = ExchangeStringUtil.hexToDec(checkStr.substring(16, 18)) + ExchangeStringUtil.hexToDec(checkStr.substring(20, 22)); |
||||
sValue = startTime + closetTime; |
||||
} |
||||
stringBuffer.append(dataType); |
||||
return sValue; |
||||
} |
||||
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue