diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java new file mode 100644 index 0000000..95d2bd4 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java @@ -0,0 +1,8 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.DataMonitorPipeOther; + +public interface IDataSentinelOtherService extends IService { + +} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java new file mode 100644 index 0000000..95d2bd4 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java @@ -0,0 +1,8 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.DataMonitorPipeOther; + +public interface IDataSentinelOtherService extends IService { + +} diff --git a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java index d6b1200..0290829 100644 --- a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java +++ b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java @@ -1,7 +1,6 @@ package com.casic.dao.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.dao.model.DataTubeOther; import com.casic.dao.model.DeviceWellView; public interface IDeviceWellViewService extends IService { diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java new file mode 100644 index 0000000..95d2bd4 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java @@ -0,0 +1,8 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.DataMonitorPipeOther; + +public interface IDataSentinelOtherService extends IService { + +} diff --git a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java index d6b1200..0290829 100644 --- a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java +++ b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java @@ -1,7 +1,6 @@ package com.casic.dao.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.dao.model.DataTubeOther; import com.casic.dao.model.DeviceWellView; public interface IDeviceWellViewService extends IService { diff --git a/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java new file mode 100644 index 0000000..be34f77 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java @@ -0,0 +1,16 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.BusDeviceMapper; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import org.springframework.stereotype.Service; + +@Service +public class BusDeviceServiceImpl extends ServiceImpl implements IBusDeviceService { + + @Override + public BusDevice getDeviceByCode(String devCode) { + return baseMapper.getOneByDevCode(devCode); + } +} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java new file mode 100644 index 0000000..95d2bd4 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java @@ -0,0 +1,8 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.DataMonitorPipeOther; + +public interface IDataSentinelOtherService extends IService { + +} diff --git a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java index d6b1200..0290829 100644 --- a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java +++ b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java @@ -1,7 +1,6 @@ package com.casic.dao.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.dao.model.DataTubeOther; import com.casic.dao.model.DeviceWellView; public interface IDeviceWellViewService extends IService { diff --git a/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java new file mode 100644 index 0000000..be34f77 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java @@ -0,0 +1,16 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.BusDeviceMapper; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import org.springframework.stereotype.Service; + +@Service +public class BusDeviceServiceImpl extends ServiceImpl implements IBusDeviceService { + + @Override + public BusDevice getDeviceByCode(String devCode) { + return baseMapper.getOneByDevCode(devCode); + } +} diff --git a/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java new file mode 100644 index 0000000..0db2007 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java @@ -0,0 +1,11 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.DataSentinelOtherMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.service.IDataSentinelOtherService; +import org.springframework.stereotype.Service; + +@Service +public class DataSentinelOtherServiceImpl extends ServiceImpl implements IDataSentinelOtherService { +} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java new file mode 100644 index 0000000..95d2bd4 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java @@ -0,0 +1,8 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.DataMonitorPipeOther; + +public interface IDataSentinelOtherService extends IService { + +} diff --git a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java index d6b1200..0290829 100644 --- a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java +++ b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java @@ -1,7 +1,6 @@ package com.casic.dao.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.dao.model.DataTubeOther; import com.casic.dao.model.DeviceWellView; public interface IDeviceWellViewService extends IService { diff --git a/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java new file mode 100644 index 0000000..be34f77 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java @@ -0,0 +1,16 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.BusDeviceMapper; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import org.springframework.stereotype.Service; + +@Service +public class BusDeviceServiceImpl extends ServiceImpl implements IBusDeviceService { + + @Override + public BusDevice getDeviceByCode(String devCode) { + return baseMapper.getOneByDevCode(devCode); + } +} diff --git a/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java new file mode 100644 index 0000000..0db2007 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java @@ -0,0 +1,11 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.DataSentinelOtherMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.service.IDataSentinelOtherService; +import org.springframework.stereotype.Service; + +@Service +public class DataSentinelOtherServiceImpl extends ServiceImpl implements IDataSentinelOtherService { +} diff --git a/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java new file mode 100644 index 0000000..d8c5ef2 --- /dev/null +++ b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java @@ -0,0 +1,111 @@ +package com.casic.protocol; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.CasicProtocol; +import org.springframework.stereotype.Component; + +@Component +public class CasicTubeProtocolImpl implements CasicProtocol { + @Override + public boolean checkFrame(String frame) { + boolean valid = checkFrameHeaderAndTail(frame); + if (valid) { + valid = checkFrameLength(frame); + } + + return valid; + } + + private boolean checkFrameHeaderAndTail(String frame) { + return (frame.substring(0, 2).equalsIgnoreCase("AA")) && + (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); + } + + private boolean checkFrameLength(String frame) { + String lengthStr = frame.substring(4, 7); + int length = Integer.parseInt(lengthStr); + + return frame.length() == length + 9; + } + + @Override + public String getDeviceType(String frame) { + return frame.substring(7, 9); + } + + @Override + public String getDeviceId(String frame) { + return frame.substring(9, 21); + } + + @Override + public String getManufacturerCode(String frame) { + return frame.substring(11, 13); + } + + @Override + public String getMessageType(String frame) { + return frame.substring(21, 23); + } + + @Override + public String getMessageSequence(String frame) { + return frame.substring(23, 25); + } + + @Override + public String getMessageBody(String frame) { + return frame.substring(26, frame.length() - 16); + } + + @Override + public JSONObject parseMessageBody(String messageBody) { + return JSONObject.parseObject(messageBody); + } + + @Override + public String getUptime(String frame) { + return frame.substring(frame.length() - 16, frame.length() - 2); + } + + @Override + public String buildFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append(frame.getMessageBody().toJSONString()); + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } + + @Override + public String buildReplyFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append("00"); // 消息响应类消息 消息体为00 + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } +} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java new file mode 100644 index 0000000..95d2bd4 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java @@ -0,0 +1,8 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.DataMonitorPipeOther; + +public interface IDataSentinelOtherService extends IService { + +} diff --git a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java index d6b1200..0290829 100644 --- a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java +++ b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java @@ -1,7 +1,6 @@ package com.casic.dao.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.dao.model.DataTubeOther; import com.casic.dao.model.DeviceWellView; public interface IDeviceWellViewService extends IService { diff --git a/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java new file mode 100644 index 0000000..be34f77 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java @@ -0,0 +1,16 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.BusDeviceMapper; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import org.springframework.stereotype.Service; + +@Service +public class BusDeviceServiceImpl extends ServiceImpl implements IBusDeviceService { + + @Override + public BusDevice getDeviceByCode(String devCode) { + return baseMapper.getOneByDevCode(devCode); + } +} diff --git a/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java new file mode 100644 index 0000000..0db2007 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java @@ -0,0 +1,11 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.DataSentinelOtherMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.service.IDataSentinelOtherService; +import org.springframework.stereotype.Service; + +@Service +public class DataSentinelOtherServiceImpl extends ServiceImpl implements IDataSentinelOtherService { +} diff --git a/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java new file mode 100644 index 0000000..d8c5ef2 --- /dev/null +++ b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java @@ -0,0 +1,111 @@ +package com.casic.protocol; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.CasicProtocol; +import org.springframework.stereotype.Component; + +@Component +public class CasicTubeProtocolImpl implements CasicProtocol { + @Override + public boolean checkFrame(String frame) { + boolean valid = checkFrameHeaderAndTail(frame); + if (valid) { + valid = checkFrameLength(frame); + } + + return valid; + } + + private boolean checkFrameHeaderAndTail(String frame) { + return (frame.substring(0, 2).equalsIgnoreCase("AA")) && + (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); + } + + private boolean checkFrameLength(String frame) { + String lengthStr = frame.substring(4, 7); + int length = Integer.parseInt(lengthStr); + + return frame.length() == length + 9; + } + + @Override + public String getDeviceType(String frame) { + return frame.substring(7, 9); + } + + @Override + public String getDeviceId(String frame) { + return frame.substring(9, 21); + } + + @Override + public String getManufacturerCode(String frame) { + return frame.substring(11, 13); + } + + @Override + public String getMessageType(String frame) { + return frame.substring(21, 23); + } + + @Override + public String getMessageSequence(String frame) { + return frame.substring(23, 25); + } + + @Override + public String getMessageBody(String frame) { + return frame.substring(26, frame.length() - 16); + } + + @Override + public JSONObject parseMessageBody(String messageBody) { + return JSONObject.parseObject(messageBody); + } + + @Override + public String getUptime(String frame) { + return frame.substring(frame.length() - 16, frame.length() - 2); + } + + @Override + public String buildFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append(frame.getMessageBody().toJSONString()); + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } + + @Override + public String buildReplyFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append("00"); // 消息响应类消息 消息体为00 + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/senitnel/controller/SentinelDataController.java b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java new file mode 100644 index 0000000..633c072 --- /dev/null +++ b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java @@ -0,0 +1,120 @@ +package com.casic.senitnel.controller; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.general.ConfigFrame; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import com.casic.senitnel.service.ISentinelFrameService; +import com.casic.util.aep.AepCommandSend; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Base64; +import java.util.Map; + +@Slf4j +@RestController +public class SentinelDataController { + + @Resource + private ISentinelFrameService frameService; + + @Resource + private IBusDeviceService deviceService; + + @RequestMapping("/sentinel/data/recv") + public Object dataRecv(@RequestBody Map map) { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + + JSONObject recvObj = (JSONObject) JSONObject.toJSON(map); + if (recvObj.containsKey("payload")) { + JSONObject payload = recvObj.getJSONObject("payload"); + String value = payload.getString("APPdata"); + + if (value.isEmpty()) { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } else { + byte[] baseBytes = Base64.getDecoder().decode(value); + String frameStr = new String(baseBytes); + + // 根据协议进行解析 + CasicFrame frame = frameService.dataParse(frameStr); + + if (frame != null) { + // 回复响应 + String replyFrameStr = frameService.replyMessage(frame.getDeviceCode(), frame.getSequence()); + + // 从数据库中获取master-api-key 回复响应消息 + BusDevice device = deviceService.getDeviceByCode(frame.getDeviceCode()); + if (device != null && StringUtils.isNotBlank(device.getMasterApiKey())) { + String masterApiKey = device.getMasterApiKey(); + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + + try { + int code = aepCommandSend.handleAndReply(replyFrameStr); + } catch (Exception ex) { + log.error("向设备回复响应异常:{}", ex.getMessage()); + } + } + + // 存库 + frameService.afterAction(frame); + } + + retObj.put("code", 200); + retObj.put("success", true); + } + } else { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } + + return retObj; + } + + @RequestMapping("/sentinel/config/send") + public Object configSend(@RequestBody Map map) throws Exception { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + CasicFrame cmdFrame = new ConfigFrame(); + cmdFrame.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + cmdFrame.setDeviceCode((String) map.get("devCode")); + cmdFrame.setSequence("01"); + cmdFrame.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + JSONObject messageBody = new JSONObject(); + messageBody.put("datas", map.get("cmdList")); + cmdFrame.setMessageBody(messageBody); + + String frameStr = frameService.doBuildCommand(cmdFrame); + + // TODO-LIST + // 这三个参数根据设备编号从数据库中取 + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + String masterApiKey = (String) map.get("masterApiKey"); + + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + int code = aepCommandSend.handleAndReply(frameStr); + + retObj.put("code", 200); + retObj.put("success", true); + retObj.put("AEPRetCode", code); + return retObj; + } +} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java new file mode 100644 index 0000000..95d2bd4 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java @@ -0,0 +1,8 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.DataMonitorPipeOther; + +public interface IDataSentinelOtherService extends IService { + +} diff --git a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java index d6b1200..0290829 100644 --- a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java +++ b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java @@ -1,7 +1,6 @@ package com.casic.dao.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.dao.model.DataTubeOther; import com.casic.dao.model.DeviceWellView; public interface IDeviceWellViewService extends IService { diff --git a/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java new file mode 100644 index 0000000..be34f77 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java @@ -0,0 +1,16 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.BusDeviceMapper; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import org.springframework.stereotype.Service; + +@Service +public class BusDeviceServiceImpl extends ServiceImpl implements IBusDeviceService { + + @Override + public BusDevice getDeviceByCode(String devCode) { + return baseMapper.getOneByDevCode(devCode); + } +} diff --git a/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java new file mode 100644 index 0000000..0db2007 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java @@ -0,0 +1,11 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.DataSentinelOtherMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.service.IDataSentinelOtherService; +import org.springframework.stereotype.Service; + +@Service +public class DataSentinelOtherServiceImpl extends ServiceImpl implements IDataSentinelOtherService { +} diff --git a/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java new file mode 100644 index 0000000..d8c5ef2 --- /dev/null +++ b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java @@ -0,0 +1,111 @@ +package com.casic.protocol; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.CasicProtocol; +import org.springframework.stereotype.Component; + +@Component +public class CasicTubeProtocolImpl implements CasicProtocol { + @Override + public boolean checkFrame(String frame) { + boolean valid = checkFrameHeaderAndTail(frame); + if (valid) { + valid = checkFrameLength(frame); + } + + return valid; + } + + private boolean checkFrameHeaderAndTail(String frame) { + return (frame.substring(0, 2).equalsIgnoreCase("AA")) && + (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); + } + + private boolean checkFrameLength(String frame) { + String lengthStr = frame.substring(4, 7); + int length = Integer.parseInt(lengthStr); + + return frame.length() == length + 9; + } + + @Override + public String getDeviceType(String frame) { + return frame.substring(7, 9); + } + + @Override + public String getDeviceId(String frame) { + return frame.substring(9, 21); + } + + @Override + public String getManufacturerCode(String frame) { + return frame.substring(11, 13); + } + + @Override + public String getMessageType(String frame) { + return frame.substring(21, 23); + } + + @Override + public String getMessageSequence(String frame) { + return frame.substring(23, 25); + } + + @Override + public String getMessageBody(String frame) { + return frame.substring(26, frame.length() - 16); + } + + @Override + public JSONObject parseMessageBody(String messageBody) { + return JSONObject.parseObject(messageBody); + } + + @Override + public String getUptime(String frame) { + return frame.substring(frame.length() - 16, frame.length() - 2); + } + + @Override + public String buildFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append(frame.getMessageBody().toJSONString()); + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } + + @Override + public String buildReplyFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append("00"); // 消息响应类消息 消息体为00 + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/senitnel/controller/SentinelDataController.java b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java new file mode 100644 index 0000000..633c072 --- /dev/null +++ b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java @@ -0,0 +1,120 @@ +package com.casic.senitnel.controller; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.general.ConfigFrame; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import com.casic.senitnel.service.ISentinelFrameService; +import com.casic.util.aep.AepCommandSend; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Base64; +import java.util.Map; + +@Slf4j +@RestController +public class SentinelDataController { + + @Resource + private ISentinelFrameService frameService; + + @Resource + private IBusDeviceService deviceService; + + @RequestMapping("/sentinel/data/recv") + public Object dataRecv(@RequestBody Map map) { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + + JSONObject recvObj = (JSONObject) JSONObject.toJSON(map); + if (recvObj.containsKey("payload")) { + JSONObject payload = recvObj.getJSONObject("payload"); + String value = payload.getString("APPdata"); + + if (value.isEmpty()) { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } else { + byte[] baseBytes = Base64.getDecoder().decode(value); + String frameStr = new String(baseBytes); + + // 根据协议进行解析 + CasicFrame frame = frameService.dataParse(frameStr); + + if (frame != null) { + // 回复响应 + String replyFrameStr = frameService.replyMessage(frame.getDeviceCode(), frame.getSequence()); + + // 从数据库中获取master-api-key 回复响应消息 + BusDevice device = deviceService.getDeviceByCode(frame.getDeviceCode()); + if (device != null && StringUtils.isNotBlank(device.getMasterApiKey())) { + String masterApiKey = device.getMasterApiKey(); + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + + try { + int code = aepCommandSend.handleAndReply(replyFrameStr); + } catch (Exception ex) { + log.error("向设备回复响应异常:{}", ex.getMessage()); + } + } + + // 存库 + frameService.afterAction(frame); + } + + retObj.put("code", 200); + retObj.put("success", true); + } + } else { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } + + return retObj; + } + + @RequestMapping("/sentinel/config/send") + public Object configSend(@RequestBody Map map) throws Exception { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + CasicFrame cmdFrame = new ConfigFrame(); + cmdFrame.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + cmdFrame.setDeviceCode((String) map.get("devCode")); + cmdFrame.setSequence("01"); + cmdFrame.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + JSONObject messageBody = new JSONObject(); + messageBody.put("datas", map.get("cmdList")); + cmdFrame.setMessageBody(messageBody); + + String frameStr = frameService.doBuildCommand(cmdFrame); + + // TODO-LIST + // 这三个参数根据设备编号从数据库中取 + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + String masterApiKey = (String) map.get("masterApiKey"); + + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + int code = aepCommandSend.handleAndReply(frameStr); + + retObj.put("code", 200); + retObj.put("success", true); + retObj.put("AEPRetCode", code); + return retObj; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java new file mode 100644 index 0000000..368af03 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java @@ -0,0 +1,82 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; +import com.casic.dao.model.DataMonitorPipeOther; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class DataFrameNCX extends DataFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + dataItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + DataItemNCX dataItem = new DataItemNCX(); + + dataItem.setLenL(dataObj.getString("LENGL")); + dataItem.setLenR(dataObj.getString("LENGR")); + dataItem.setBat(dataObj.getString("BAT")); + dataItem.setCh4L(dataObj.getString("CH4L")); + dataItem.setCh4R(dataObj.getString("CH4R")); + dataItem.setSlope(dataObj.getString("SLOPING")); + dataItem.setDestroy(dataObj.getString("DESTROY")); + dataItem.setLeak(dataObj.getString("LEAK")); + dataItem.setDiscL(dataObj.getString("DISCL")); + dataItem.setDiscR(dataObj.getString("DISCR")); + dataItem.setVibL(dataObj.getString("VIBL")); + dataItem.setVibR(dataObj.getString("VIBR")); + dataItem.setTime(dataObj.getString("UPTIME")); + + dataItemList.add(dataItem); + } + } + + @Override + public List toDataModelList() { + List dataList = new ArrayList<>(); + for (DataItem dataItem : dataItemList) { + DataMonitorPipeOther data = new DataMonitorPipeOther(); + + data.setDevcode(getDeviceCode()); + data.setLeftLength(((DataItemNCX)dataItem).getLenL()); + data.setRightLength(((DataItemNCX)dataItem).getLenR()); + data.setLeftGas(((DataItemNCX)dataItem).getCh4L()); + data.setRightGas(((DataItemNCX)dataItem).getCh4R()); + data.setVbat(((DataItemNCX)dataItem).getBat()); + data.setPipeInclineAlarm(((DataItemNCX)dataItem).getSlope()); + data.setPipeBreakAlarm(((DataItemNCX)dataItem).getDestroy()); + data.setGasAlarm(((DataItemNCX)dataItem).getLeak()); + data.setLeftOfflineAlarm(((DataItemNCX)dataItem).getDiscL()); + data.setRightOfflineAlarm(((DataItemNCX)dataItem).getDiscR()); + data.setLeftVibrateAlarm(((DataItemNCX)dataItem).getVibL()); + data.setRightVibrateAlarm(((DataItemNCX)dataItem).getVibR()); + data.setUptime(LocalDateTime.parse(((DataItemNCX)dataItem).getTime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 采集时间 + data.setLogtime(LocalDateTime.parse(getUptime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 上报时间 + + dataList.add(data); + } + + return dataList; + } +} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java new file mode 100644 index 0000000..95d2bd4 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java @@ -0,0 +1,8 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.DataMonitorPipeOther; + +public interface IDataSentinelOtherService extends IService { + +} diff --git a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java index d6b1200..0290829 100644 --- a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java +++ b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java @@ -1,7 +1,6 @@ package com.casic.dao.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.dao.model.DataTubeOther; import com.casic.dao.model.DeviceWellView; public interface IDeviceWellViewService extends IService { diff --git a/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java new file mode 100644 index 0000000..be34f77 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java @@ -0,0 +1,16 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.BusDeviceMapper; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import org.springframework.stereotype.Service; + +@Service +public class BusDeviceServiceImpl extends ServiceImpl implements IBusDeviceService { + + @Override + public BusDevice getDeviceByCode(String devCode) { + return baseMapper.getOneByDevCode(devCode); + } +} diff --git a/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java new file mode 100644 index 0000000..0db2007 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java @@ -0,0 +1,11 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.DataSentinelOtherMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.service.IDataSentinelOtherService; +import org.springframework.stereotype.Service; + +@Service +public class DataSentinelOtherServiceImpl extends ServiceImpl implements IDataSentinelOtherService { +} diff --git a/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java new file mode 100644 index 0000000..d8c5ef2 --- /dev/null +++ b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java @@ -0,0 +1,111 @@ +package com.casic.protocol; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.CasicProtocol; +import org.springframework.stereotype.Component; + +@Component +public class CasicTubeProtocolImpl implements CasicProtocol { + @Override + public boolean checkFrame(String frame) { + boolean valid = checkFrameHeaderAndTail(frame); + if (valid) { + valid = checkFrameLength(frame); + } + + return valid; + } + + private boolean checkFrameHeaderAndTail(String frame) { + return (frame.substring(0, 2).equalsIgnoreCase("AA")) && + (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); + } + + private boolean checkFrameLength(String frame) { + String lengthStr = frame.substring(4, 7); + int length = Integer.parseInt(lengthStr); + + return frame.length() == length + 9; + } + + @Override + public String getDeviceType(String frame) { + return frame.substring(7, 9); + } + + @Override + public String getDeviceId(String frame) { + return frame.substring(9, 21); + } + + @Override + public String getManufacturerCode(String frame) { + return frame.substring(11, 13); + } + + @Override + public String getMessageType(String frame) { + return frame.substring(21, 23); + } + + @Override + public String getMessageSequence(String frame) { + return frame.substring(23, 25); + } + + @Override + public String getMessageBody(String frame) { + return frame.substring(26, frame.length() - 16); + } + + @Override + public JSONObject parseMessageBody(String messageBody) { + return JSONObject.parseObject(messageBody); + } + + @Override + public String getUptime(String frame) { + return frame.substring(frame.length() - 16, frame.length() - 2); + } + + @Override + public String buildFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append(frame.getMessageBody().toJSONString()); + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } + + @Override + public String buildReplyFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append("00"); // 消息响应类消息 消息体为00 + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/senitnel/controller/SentinelDataController.java b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java new file mode 100644 index 0000000..633c072 --- /dev/null +++ b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java @@ -0,0 +1,120 @@ +package com.casic.senitnel.controller; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.general.ConfigFrame; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import com.casic.senitnel.service.ISentinelFrameService; +import com.casic.util.aep.AepCommandSend; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Base64; +import java.util.Map; + +@Slf4j +@RestController +public class SentinelDataController { + + @Resource + private ISentinelFrameService frameService; + + @Resource + private IBusDeviceService deviceService; + + @RequestMapping("/sentinel/data/recv") + public Object dataRecv(@RequestBody Map map) { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + + JSONObject recvObj = (JSONObject) JSONObject.toJSON(map); + if (recvObj.containsKey("payload")) { + JSONObject payload = recvObj.getJSONObject("payload"); + String value = payload.getString("APPdata"); + + if (value.isEmpty()) { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } else { + byte[] baseBytes = Base64.getDecoder().decode(value); + String frameStr = new String(baseBytes); + + // 根据协议进行解析 + CasicFrame frame = frameService.dataParse(frameStr); + + if (frame != null) { + // 回复响应 + String replyFrameStr = frameService.replyMessage(frame.getDeviceCode(), frame.getSequence()); + + // 从数据库中获取master-api-key 回复响应消息 + BusDevice device = deviceService.getDeviceByCode(frame.getDeviceCode()); + if (device != null && StringUtils.isNotBlank(device.getMasterApiKey())) { + String masterApiKey = device.getMasterApiKey(); + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + + try { + int code = aepCommandSend.handleAndReply(replyFrameStr); + } catch (Exception ex) { + log.error("向设备回复响应异常:{}", ex.getMessage()); + } + } + + // 存库 + frameService.afterAction(frame); + } + + retObj.put("code", 200); + retObj.put("success", true); + } + } else { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } + + return retObj; + } + + @RequestMapping("/sentinel/config/send") + public Object configSend(@RequestBody Map map) throws Exception { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + CasicFrame cmdFrame = new ConfigFrame(); + cmdFrame.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + cmdFrame.setDeviceCode((String) map.get("devCode")); + cmdFrame.setSequence("01"); + cmdFrame.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + JSONObject messageBody = new JSONObject(); + messageBody.put("datas", map.get("cmdList")); + cmdFrame.setMessageBody(messageBody); + + String frameStr = frameService.doBuildCommand(cmdFrame); + + // TODO-LIST + // 这三个参数根据设备编号从数据库中取 + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + String masterApiKey = (String) map.get("masterApiKey"); + + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + int code = aepCommandSend.handleAndReply(frameStr); + + retObj.put("code", 200); + retObj.put("success", true); + retObj.put("AEPRetCode", code); + return retObj; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java new file mode 100644 index 0000000..368af03 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java @@ -0,0 +1,82 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; +import com.casic.dao.model.DataMonitorPipeOther; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class DataFrameNCX extends DataFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + dataItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + DataItemNCX dataItem = new DataItemNCX(); + + dataItem.setLenL(dataObj.getString("LENGL")); + dataItem.setLenR(dataObj.getString("LENGR")); + dataItem.setBat(dataObj.getString("BAT")); + dataItem.setCh4L(dataObj.getString("CH4L")); + dataItem.setCh4R(dataObj.getString("CH4R")); + dataItem.setSlope(dataObj.getString("SLOPING")); + dataItem.setDestroy(dataObj.getString("DESTROY")); + dataItem.setLeak(dataObj.getString("LEAK")); + dataItem.setDiscL(dataObj.getString("DISCL")); + dataItem.setDiscR(dataObj.getString("DISCR")); + dataItem.setVibL(dataObj.getString("VIBL")); + dataItem.setVibR(dataObj.getString("VIBR")); + dataItem.setTime(dataObj.getString("UPTIME")); + + dataItemList.add(dataItem); + } + } + + @Override + public List toDataModelList() { + List dataList = new ArrayList<>(); + for (DataItem dataItem : dataItemList) { + DataMonitorPipeOther data = new DataMonitorPipeOther(); + + data.setDevcode(getDeviceCode()); + data.setLeftLength(((DataItemNCX)dataItem).getLenL()); + data.setRightLength(((DataItemNCX)dataItem).getLenR()); + data.setLeftGas(((DataItemNCX)dataItem).getCh4L()); + data.setRightGas(((DataItemNCX)dataItem).getCh4R()); + data.setVbat(((DataItemNCX)dataItem).getBat()); + data.setPipeInclineAlarm(((DataItemNCX)dataItem).getSlope()); + data.setPipeBreakAlarm(((DataItemNCX)dataItem).getDestroy()); + data.setGasAlarm(((DataItemNCX)dataItem).getLeak()); + data.setLeftOfflineAlarm(((DataItemNCX)dataItem).getDiscL()); + data.setRightOfflineAlarm(((DataItemNCX)dataItem).getDiscR()); + data.setLeftVibrateAlarm(((DataItemNCX)dataItem).getVibL()); + data.setRightVibrateAlarm(((DataItemNCX)dataItem).getVibR()); + data.setUptime(LocalDateTime.parse(((DataItemNCX)dataItem).getTime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 采集时间 + data.setLogtime(LocalDateTime.parse(getUptime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 上报时间 + + dataList.add(data); + } + + return dataList; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java new file mode 100644 index 0000000..372ac73 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java @@ -0,0 +1,31 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.DataItem; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class DataItemNCX extends DataItem { + String lenL; // 左侧指示带长度 + String lenR; // 右侧指示带长度 + String ch4L; // 左侧甲烷浓度值 + String ch4R; // 右侧甲烷浓度值 + String bat; // 电池电压 + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String spare; // 备用 + String time; // 采集时间 + + @Override + public String toString() { + return "气体浓度值:" + "(" + ch4L + "," + ch4R + ")" + "%LEL;" + + "电池电压值:" + bat + "v;" + + "采样时间:" + time; + } +} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java new file mode 100644 index 0000000..95d2bd4 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java @@ -0,0 +1,8 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.DataMonitorPipeOther; + +public interface IDataSentinelOtherService extends IService { + +} diff --git a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java index d6b1200..0290829 100644 --- a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java +++ b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java @@ -1,7 +1,6 @@ package com.casic.dao.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.dao.model.DataTubeOther; import com.casic.dao.model.DeviceWellView; public interface IDeviceWellViewService extends IService { diff --git a/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java new file mode 100644 index 0000000..be34f77 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java @@ -0,0 +1,16 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.BusDeviceMapper; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import org.springframework.stereotype.Service; + +@Service +public class BusDeviceServiceImpl extends ServiceImpl implements IBusDeviceService { + + @Override + public BusDevice getDeviceByCode(String devCode) { + return baseMapper.getOneByDevCode(devCode); + } +} diff --git a/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java new file mode 100644 index 0000000..0db2007 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java @@ -0,0 +1,11 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.DataSentinelOtherMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.service.IDataSentinelOtherService; +import org.springframework.stereotype.Service; + +@Service +public class DataSentinelOtherServiceImpl extends ServiceImpl implements IDataSentinelOtherService { +} diff --git a/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java new file mode 100644 index 0000000..d8c5ef2 --- /dev/null +++ b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java @@ -0,0 +1,111 @@ +package com.casic.protocol; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.CasicProtocol; +import org.springframework.stereotype.Component; + +@Component +public class CasicTubeProtocolImpl implements CasicProtocol { + @Override + public boolean checkFrame(String frame) { + boolean valid = checkFrameHeaderAndTail(frame); + if (valid) { + valid = checkFrameLength(frame); + } + + return valid; + } + + private boolean checkFrameHeaderAndTail(String frame) { + return (frame.substring(0, 2).equalsIgnoreCase("AA")) && + (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); + } + + private boolean checkFrameLength(String frame) { + String lengthStr = frame.substring(4, 7); + int length = Integer.parseInt(lengthStr); + + return frame.length() == length + 9; + } + + @Override + public String getDeviceType(String frame) { + return frame.substring(7, 9); + } + + @Override + public String getDeviceId(String frame) { + return frame.substring(9, 21); + } + + @Override + public String getManufacturerCode(String frame) { + return frame.substring(11, 13); + } + + @Override + public String getMessageType(String frame) { + return frame.substring(21, 23); + } + + @Override + public String getMessageSequence(String frame) { + return frame.substring(23, 25); + } + + @Override + public String getMessageBody(String frame) { + return frame.substring(26, frame.length() - 16); + } + + @Override + public JSONObject parseMessageBody(String messageBody) { + return JSONObject.parseObject(messageBody); + } + + @Override + public String getUptime(String frame) { + return frame.substring(frame.length() - 16, frame.length() - 2); + } + + @Override + public String buildFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append(frame.getMessageBody().toJSONString()); + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } + + @Override + public String buildReplyFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append("00"); // 消息响应类消息 消息体为00 + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/senitnel/controller/SentinelDataController.java b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java new file mode 100644 index 0000000..633c072 --- /dev/null +++ b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java @@ -0,0 +1,120 @@ +package com.casic.senitnel.controller; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.general.ConfigFrame; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import com.casic.senitnel.service.ISentinelFrameService; +import com.casic.util.aep.AepCommandSend; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Base64; +import java.util.Map; + +@Slf4j +@RestController +public class SentinelDataController { + + @Resource + private ISentinelFrameService frameService; + + @Resource + private IBusDeviceService deviceService; + + @RequestMapping("/sentinel/data/recv") + public Object dataRecv(@RequestBody Map map) { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + + JSONObject recvObj = (JSONObject) JSONObject.toJSON(map); + if (recvObj.containsKey("payload")) { + JSONObject payload = recvObj.getJSONObject("payload"); + String value = payload.getString("APPdata"); + + if (value.isEmpty()) { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } else { + byte[] baseBytes = Base64.getDecoder().decode(value); + String frameStr = new String(baseBytes); + + // 根据协议进行解析 + CasicFrame frame = frameService.dataParse(frameStr); + + if (frame != null) { + // 回复响应 + String replyFrameStr = frameService.replyMessage(frame.getDeviceCode(), frame.getSequence()); + + // 从数据库中获取master-api-key 回复响应消息 + BusDevice device = deviceService.getDeviceByCode(frame.getDeviceCode()); + if (device != null && StringUtils.isNotBlank(device.getMasterApiKey())) { + String masterApiKey = device.getMasterApiKey(); + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + + try { + int code = aepCommandSend.handleAndReply(replyFrameStr); + } catch (Exception ex) { + log.error("向设备回复响应异常:{}", ex.getMessage()); + } + } + + // 存库 + frameService.afterAction(frame); + } + + retObj.put("code", 200); + retObj.put("success", true); + } + } else { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } + + return retObj; + } + + @RequestMapping("/sentinel/config/send") + public Object configSend(@RequestBody Map map) throws Exception { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + CasicFrame cmdFrame = new ConfigFrame(); + cmdFrame.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + cmdFrame.setDeviceCode((String) map.get("devCode")); + cmdFrame.setSequence("01"); + cmdFrame.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + JSONObject messageBody = new JSONObject(); + messageBody.put("datas", map.get("cmdList")); + cmdFrame.setMessageBody(messageBody); + + String frameStr = frameService.doBuildCommand(cmdFrame); + + // TODO-LIST + // 这三个参数根据设备编号从数据库中取 + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + String masterApiKey = (String) map.get("masterApiKey"); + + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + int code = aepCommandSend.handleAndReply(frameStr); + + retObj.put("code", 200); + retObj.put("success", true); + retObj.put("AEPRetCode", code); + return retObj; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java new file mode 100644 index 0000000..368af03 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java @@ -0,0 +1,82 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; +import com.casic.dao.model.DataMonitorPipeOther; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class DataFrameNCX extends DataFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + dataItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + DataItemNCX dataItem = new DataItemNCX(); + + dataItem.setLenL(dataObj.getString("LENGL")); + dataItem.setLenR(dataObj.getString("LENGR")); + dataItem.setBat(dataObj.getString("BAT")); + dataItem.setCh4L(dataObj.getString("CH4L")); + dataItem.setCh4R(dataObj.getString("CH4R")); + dataItem.setSlope(dataObj.getString("SLOPING")); + dataItem.setDestroy(dataObj.getString("DESTROY")); + dataItem.setLeak(dataObj.getString("LEAK")); + dataItem.setDiscL(dataObj.getString("DISCL")); + dataItem.setDiscR(dataObj.getString("DISCR")); + dataItem.setVibL(dataObj.getString("VIBL")); + dataItem.setVibR(dataObj.getString("VIBR")); + dataItem.setTime(dataObj.getString("UPTIME")); + + dataItemList.add(dataItem); + } + } + + @Override + public List toDataModelList() { + List dataList = new ArrayList<>(); + for (DataItem dataItem : dataItemList) { + DataMonitorPipeOther data = new DataMonitorPipeOther(); + + data.setDevcode(getDeviceCode()); + data.setLeftLength(((DataItemNCX)dataItem).getLenL()); + data.setRightLength(((DataItemNCX)dataItem).getLenR()); + data.setLeftGas(((DataItemNCX)dataItem).getCh4L()); + data.setRightGas(((DataItemNCX)dataItem).getCh4R()); + data.setVbat(((DataItemNCX)dataItem).getBat()); + data.setPipeInclineAlarm(((DataItemNCX)dataItem).getSlope()); + data.setPipeBreakAlarm(((DataItemNCX)dataItem).getDestroy()); + data.setGasAlarm(((DataItemNCX)dataItem).getLeak()); + data.setLeftOfflineAlarm(((DataItemNCX)dataItem).getDiscL()); + data.setRightOfflineAlarm(((DataItemNCX)dataItem).getDiscR()); + data.setLeftVibrateAlarm(((DataItemNCX)dataItem).getVibL()); + data.setRightVibrateAlarm(((DataItemNCX)dataItem).getVibR()); + data.setUptime(LocalDateTime.parse(((DataItemNCX)dataItem).getTime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 采集时间 + data.setLogtime(LocalDateTime.parse(getUptime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 上报时间 + + dataList.add(data); + } + + return dataList; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java new file mode 100644 index 0000000..372ac73 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java @@ -0,0 +1,31 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.DataItem; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class DataItemNCX extends DataItem { + String lenL; // 左侧指示带长度 + String lenR; // 右侧指示带长度 + String ch4L; // 左侧甲烷浓度值 + String ch4R; // 右侧甲烷浓度值 + String bat; // 电池电压 + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String spare; // 备用 + String time; // 采集时间 + + @Override + public String toString() { + return "气体浓度值:" + "(" + ch4L + "," + ch4R + ")" + "%LEL;" + + "电池电压值:" + bat + "v;" + + "采样时间:" + time; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java new file mode 100644 index 0000000..b3bbcf4 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java @@ -0,0 +1,43 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.EventFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class EventFrameNCX extends EventFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + eventItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + EventItemNCX eventItem = new EventItemNCX(); + + eventItem.setSlope(dataObj.getString("SLOPING")); + eventItem.setDestroy(dataObj.getString("DESTROY")); + eventItem.setLeak(dataObj.getString("LEAK")); + eventItem.setDiscL(dataObj.getString("DISCL")); + eventItem.setDiscR(dataObj.getString("DISCR")); + eventItem.setVibL(dataObj.getString("VIBL")); + eventItem.setVibR(dataObj.getString("VIBR")); + eventItem.setTime(dataObj.getString("UPTIME")); + + eventItemList.add(eventItem); + } + } +} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java new file mode 100644 index 0000000..95d2bd4 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java @@ -0,0 +1,8 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.DataMonitorPipeOther; + +public interface IDataSentinelOtherService extends IService { + +} diff --git a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java index d6b1200..0290829 100644 --- a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java +++ b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java @@ -1,7 +1,6 @@ package com.casic.dao.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.dao.model.DataTubeOther; import com.casic.dao.model.DeviceWellView; public interface IDeviceWellViewService extends IService { diff --git a/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java new file mode 100644 index 0000000..be34f77 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java @@ -0,0 +1,16 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.BusDeviceMapper; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import org.springframework.stereotype.Service; + +@Service +public class BusDeviceServiceImpl extends ServiceImpl implements IBusDeviceService { + + @Override + public BusDevice getDeviceByCode(String devCode) { + return baseMapper.getOneByDevCode(devCode); + } +} diff --git a/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java new file mode 100644 index 0000000..0db2007 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java @@ -0,0 +1,11 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.DataSentinelOtherMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.service.IDataSentinelOtherService; +import org.springframework.stereotype.Service; + +@Service +public class DataSentinelOtherServiceImpl extends ServiceImpl implements IDataSentinelOtherService { +} diff --git a/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java new file mode 100644 index 0000000..d8c5ef2 --- /dev/null +++ b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java @@ -0,0 +1,111 @@ +package com.casic.protocol; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.CasicProtocol; +import org.springframework.stereotype.Component; + +@Component +public class CasicTubeProtocolImpl implements CasicProtocol { + @Override + public boolean checkFrame(String frame) { + boolean valid = checkFrameHeaderAndTail(frame); + if (valid) { + valid = checkFrameLength(frame); + } + + return valid; + } + + private boolean checkFrameHeaderAndTail(String frame) { + return (frame.substring(0, 2).equalsIgnoreCase("AA")) && + (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); + } + + private boolean checkFrameLength(String frame) { + String lengthStr = frame.substring(4, 7); + int length = Integer.parseInt(lengthStr); + + return frame.length() == length + 9; + } + + @Override + public String getDeviceType(String frame) { + return frame.substring(7, 9); + } + + @Override + public String getDeviceId(String frame) { + return frame.substring(9, 21); + } + + @Override + public String getManufacturerCode(String frame) { + return frame.substring(11, 13); + } + + @Override + public String getMessageType(String frame) { + return frame.substring(21, 23); + } + + @Override + public String getMessageSequence(String frame) { + return frame.substring(23, 25); + } + + @Override + public String getMessageBody(String frame) { + return frame.substring(26, frame.length() - 16); + } + + @Override + public JSONObject parseMessageBody(String messageBody) { + return JSONObject.parseObject(messageBody); + } + + @Override + public String getUptime(String frame) { + return frame.substring(frame.length() - 16, frame.length() - 2); + } + + @Override + public String buildFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append(frame.getMessageBody().toJSONString()); + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } + + @Override + public String buildReplyFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append("00"); // 消息响应类消息 消息体为00 + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/senitnel/controller/SentinelDataController.java b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java new file mode 100644 index 0000000..633c072 --- /dev/null +++ b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java @@ -0,0 +1,120 @@ +package com.casic.senitnel.controller; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.general.ConfigFrame; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import com.casic.senitnel.service.ISentinelFrameService; +import com.casic.util.aep.AepCommandSend; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Base64; +import java.util.Map; + +@Slf4j +@RestController +public class SentinelDataController { + + @Resource + private ISentinelFrameService frameService; + + @Resource + private IBusDeviceService deviceService; + + @RequestMapping("/sentinel/data/recv") + public Object dataRecv(@RequestBody Map map) { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + + JSONObject recvObj = (JSONObject) JSONObject.toJSON(map); + if (recvObj.containsKey("payload")) { + JSONObject payload = recvObj.getJSONObject("payload"); + String value = payload.getString("APPdata"); + + if (value.isEmpty()) { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } else { + byte[] baseBytes = Base64.getDecoder().decode(value); + String frameStr = new String(baseBytes); + + // 根据协议进行解析 + CasicFrame frame = frameService.dataParse(frameStr); + + if (frame != null) { + // 回复响应 + String replyFrameStr = frameService.replyMessage(frame.getDeviceCode(), frame.getSequence()); + + // 从数据库中获取master-api-key 回复响应消息 + BusDevice device = deviceService.getDeviceByCode(frame.getDeviceCode()); + if (device != null && StringUtils.isNotBlank(device.getMasterApiKey())) { + String masterApiKey = device.getMasterApiKey(); + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + + try { + int code = aepCommandSend.handleAndReply(replyFrameStr); + } catch (Exception ex) { + log.error("向设备回复响应异常:{}", ex.getMessage()); + } + } + + // 存库 + frameService.afterAction(frame); + } + + retObj.put("code", 200); + retObj.put("success", true); + } + } else { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } + + return retObj; + } + + @RequestMapping("/sentinel/config/send") + public Object configSend(@RequestBody Map map) throws Exception { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + CasicFrame cmdFrame = new ConfigFrame(); + cmdFrame.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + cmdFrame.setDeviceCode((String) map.get("devCode")); + cmdFrame.setSequence("01"); + cmdFrame.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + JSONObject messageBody = new JSONObject(); + messageBody.put("datas", map.get("cmdList")); + cmdFrame.setMessageBody(messageBody); + + String frameStr = frameService.doBuildCommand(cmdFrame); + + // TODO-LIST + // 这三个参数根据设备编号从数据库中取 + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + String masterApiKey = (String) map.get("masterApiKey"); + + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + int code = aepCommandSend.handleAndReply(frameStr); + + retObj.put("code", 200); + retObj.put("success", true); + retObj.put("AEPRetCode", code); + return retObj; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java new file mode 100644 index 0000000..368af03 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java @@ -0,0 +1,82 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; +import com.casic.dao.model.DataMonitorPipeOther; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class DataFrameNCX extends DataFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + dataItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + DataItemNCX dataItem = new DataItemNCX(); + + dataItem.setLenL(dataObj.getString("LENGL")); + dataItem.setLenR(dataObj.getString("LENGR")); + dataItem.setBat(dataObj.getString("BAT")); + dataItem.setCh4L(dataObj.getString("CH4L")); + dataItem.setCh4R(dataObj.getString("CH4R")); + dataItem.setSlope(dataObj.getString("SLOPING")); + dataItem.setDestroy(dataObj.getString("DESTROY")); + dataItem.setLeak(dataObj.getString("LEAK")); + dataItem.setDiscL(dataObj.getString("DISCL")); + dataItem.setDiscR(dataObj.getString("DISCR")); + dataItem.setVibL(dataObj.getString("VIBL")); + dataItem.setVibR(dataObj.getString("VIBR")); + dataItem.setTime(dataObj.getString("UPTIME")); + + dataItemList.add(dataItem); + } + } + + @Override + public List toDataModelList() { + List dataList = new ArrayList<>(); + for (DataItem dataItem : dataItemList) { + DataMonitorPipeOther data = new DataMonitorPipeOther(); + + data.setDevcode(getDeviceCode()); + data.setLeftLength(((DataItemNCX)dataItem).getLenL()); + data.setRightLength(((DataItemNCX)dataItem).getLenR()); + data.setLeftGas(((DataItemNCX)dataItem).getCh4L()); + data.setRightGas(((DataItemNCX)dataItem).getCh4R()); + data.setVbat(((DataItemNCX)dataItem).getBat()); + data.setPipeInclineAlarm(((DataItemNCX)dataItem).getSlope()); + data.setPipeBreakAlarm(((DataItemNCX)dataItem).getDestroy()); + data.setGasAlarm(((DataItemNCX)dataItem).getLeak()); + data.setLeftOfflineAlarm(((DataItemNCX)dataItem).getDiscL()); + data.setRightOfflineAlarm(((DataItemNCX)dataItem).getDiscR()); + data.setLeftVibrateAlarm(((DataItemNCX)dataItem).getVibL()); + data.setRightVibrateAlarm(((DataItemNCX)dataItem).getVibR()); + data.setUptime(LocalDateTime.parse(((DataItemNCX)dataItem).getTime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 采集时间 + data.setLogtime(LocalDateTime.parse(getUptime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 上报时间 + + dataList.add(data); + } + + return dataList; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java new file mode 100644 index 0000000..372ac73 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java @@ -0,0 +1,31 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.DataItem; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class DataItemNCX extends DataItem { + String lenL; // 左侧指示带长度 + String lenR; // 右侧指示带长度 + String ch4L; // 左侧甲烷浓度值 + String ch4R; // 右侧甲烷浓度值 + String bat; // 电池电压 + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String spare; // 备用 + String time; // 采集时间 + + @Override + public String toString() { + return "气体浓度值:" + "(" + ch4L + "," + ch4R + ")" + "%LEL;" + + "电池电压值:" + bat + "v;" + + "采样时间:" + time; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java new file mode 100644 index 0000000..b3bbcf4 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java @@ -0,0 +1,43 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.EventFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class EventFrameNCX extends EventFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + eventItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + EventItemNCX eventItem = new EventItemNCX(); + + eventItem.setSlope(dataObj.getString("SLOPING")); + eventItem.setDestroy(dataObj.getString("DESTROY")); + eventItem.setLeak(dataObj.getString("LEAK")); + eventItem.setDiscL(dataObj.getString("DISCL")); + eventItem.setDiscR(dataObj.getString("DISCR")); + eventItem.setVibL(dataObj.getString("VIBL")); + eventItem.setVibR(dataObj.getString("VIBR")); + eventItem.setTime(dataObj.getString("UPTIME")); + + eventItemList.add(eventItem); + } + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java new file mode 100644 index 0000000..1a560d0 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java @@ -0,0 +1,49 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.EventItem; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.commons.lang3.StringUtils; + +@EqualsAndHashCode(callSuper = true) +@Data +public class EventItemNCX extends EventItem { + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String time; // 采集时间 + + @Override + public String toString() { + String str = ""; + if (StringUtils.isNotBlank(slope) && slope.equalsIgnoreCase("1")) { + str += "[倾斜报警]"; + } + if (StringUtils.isNotBlank(destroy) && destroy.equalsIgnoreCase("1")) { + str += "[破坏报警]"; + } + if (StringUtils.isNotBlank(leak) && leak.equalsIgnoreCase("1")) { + str += "[甲烷泄漏报警]"; + } + if (StringUtils.isNotBlank(discL) && discL.equalsIgnoreCase("1")) { + str += "[左侧断线报警]"; + } + if (StringUtils.isNotBlank(discR) && discR.equalsIgnoreCase("1")) { + str += "[右侧断线报警]"; + } + if (StringUtils.isNotBlank(vibL) && vibL.equalsIgnoreCase("1")) { + str += "[左侧振动报警]"; + } + if (StringUtils.isNotBlank(vibR) && vibR.equalsIgnoreCase("1")) { + str += "[右侧振动报警]"; + } + str += "采样时间:" + time; + + return str; + + } +} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java new file mode 100644 index 0000000..95d2bd4 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java @@ -0,0 +1,8 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.DataMonitorPipeOther; + +public interface IDataSentinelOtherService extends IService { + +} diff --git a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java index d6b1200..0290829 100644 --- a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java +++ b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java @@ -1,7 +1,6 @@ package com.casic.dao.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.dao.model.DataTubeOther; import com.casic.dao.model.DeviceWellView; public interface IDeviceWellViewService extends IService { diff --git a/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java new file mode 100644 index 0000000..be34f77 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java @@ -0,0 +1,16 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.BusDeviceMapper; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import org.springframework.stereotype.Service; + +@Service +public class BusDeviceServiceImpl extends ServiceImpl implements IBusDeviceService { + + @Override + public BusDevice getDeviceByCode(String devCode) { + return baseMapper.getOneByDevCode(devCode); + } +} diff --git a/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java new file mode 100644 index 0000000..0db2007 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java @@ -0,0 +1,11 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.DataSentinelOtherMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.service.IDataSentinelOtherService; +import org.springframework.stereotype.Service; + +@Service +public class DataSentinelOtherServiceImpl extends ServiceImpl implements IDataSentinelOtherService { +} diff --git a/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java new file mode 100644 index 0000000..d8c5ef2 --- /dev/null +++ b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java @@ -0,0 +1,111 @@ +package com.casic.protocol; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.CasicProtocol; +import org.springframework.stereotype.Component; + +@Component +public class CasicTubeProtocolImpl implements CasicProtocol { + @Override + public boolean checkFrame(String frame) { + boolean valid = checkFrameHeaderAndTail(frame); + if (valid) { + valid = checkFrameLength(frame); + } + + return valid; + } + + private boolean checkFrameHeaderAndTail(String frame) { + return (frame.substring(0, 2).equalsIgnoreCase("AA")) && + (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); + } + + private boolean checkFrameLength(String frame) { + String lengthStr = frame.substring(4, 7); + int length = Integer.parseInt(lengthStr); + + return frame.length() == length + 9; + } + + @Override + public String getDeviceType(String frame) { + return frame.substring(7, 9); + } + + @Override + public String getDeviceId(String frame) { + return frame.substring(9, 21); + } + + @Override + public String getManufacturerCode(String frame) { + return frame.substring(11, 13); + } + + @Override + public String getMessageType(String frame) { + return frame.substring(21, 23); + } + + @Override + public String getMessageSequence(String frame) { + return frame.substring(23, 25); + } + + @Override + public String getMessageBody(String frame) { + return frame.substring(26, frame.length() - 16); + } + + @Override + public JSONObject parseMessageBody(String messageBody) { + return JSONObject.parseObject(messageBody); + } + + @Override + public String getUptime(String frame) { + return frame.substring(frame.length() - 16, frame.length() - 2); + } + + @Override + public String buildFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append(frame.getMessageBody().toJSONString()); + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } + + @Override + public String buildReplyFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append("00"); // 消息响应类消息 消息体为00 + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/senitnel/controller/SentinelDataController.java b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java new file mode 100644 index 0000000..633c072 --- /dev/null +++ b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java @@ -0,0 +1,120 @@ +package com.casic.senitnel.controller; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.general.ConfigFrame; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import com.casic.senitnel.service.ISentinelFrameService; +import com.casic.util.aep.AepCommandSend; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Base64; +import java.util.Map; + +@Slf4j +@RestController +public class SentinelDataController { + + @Resource + private ISentinelFrameService frameService; + + @Resource + private IBusDeviceService deviceService; + + @RequestMapping("/sentinel/data/recv") + public Object dataRecv(@RequestBody Map map) { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + + JSONObject recvObj = (JSONObject) JSONObject.toJSON(map); + if (recvObj.containsKey("payload")) { + JSONObject payload = recvObj.getJSONObject("payload"); + String value = payload.getString("APPdata"); + + if (value.isEmpty()) { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } else { + byte[] baseBytes = Base64.getDecoder().decode(value); + String frameStr = new String(baseBytes); + + // 根据协议进行解析 + CasicFrame frame = frameService.dataParse(frameStr); + + if (frame != null) { + // 回复响应 + String replyFrameStr = frameService.replyMessage(frame.getDeviceCode(), frame.getSequence()); + + // 从数据库中获取master-api-key 回复响应消息 + BusDevice device = deviceService.getDeviceByCode(frame.getDeviceCode()); + if (device != null && StringUtils.isNotBlank(device.getMasterApiKey())) { + String masterApiKey = device.getMasterApiKey(); + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + + try { + int code = aepCommandSend.handleAndReply(replyFrameStr); + } catch (Exception ex) { + log.error("向设备回复响应异常:{}", ex.getMessage()); + } + } + + // 存库 + frameService.afterAction(frame); + } + + retObj.put("code", 200); + retObj.put("success", true); + } + } else { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } + + return retObj; + } + + @RequestMapping("/sentinel/config/send") + public Object configSend(@RequestBody Map map) throws Exception { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + CasicFrame cmdFrame = new ConfigFrame(); + cmdFrame.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + cmdFrame.setDeviceCode((String) map.get("devCode")); + cmdFrame.setSequence("01"); + cmdFrame.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + JSONObject messageBody = new JSONObject(); + messageBody.put("datas", map.get("cmdList")); + cmdFrame.setMessageBody(messageBody); + + String frameStr = frameService.doBuildCommand(cmdFrame); + + // TODO-LIST + // 这三个参数根据设备编号从数据库中取 + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + String masterApiKey = (String) map.get("masterApiKey"); + + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + int code = aepCommandSend.handleAndReply(frameStr); + + retObj.put("code", 200); + retObj.put("success", true); + retObj.put("AEPRetCode", code); + return retObj; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java new file mode 100644 index 0000000..368af03 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java @@ -0,0 +1,82 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; +import com.casic.dao.model.DataMonitorPipeOther; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class DataFrameNCX extends DataFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + dataItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + DataItemNCX dataItem = new DataItemNCX(); + + dataItem.setLenL(dataObj.getString("LENGL")); + dataItem.setLenR(dataObj.getString("LENGR")); + dataItem.setBat(dataObj.getString("BAT")); + dataItem.setCh4L(dataObj.getString("CH4L")); + dataItem.setCh4R(dataObj.getString("CH4R")); + dataItem.setSlope(dataObj.getString("SLOPING")); + dataItem.setDestroy(dataObj.getString("DESTROY")); + dataItem.setLeak(dataObj.getString("LEAK")); + dataItem.setDiscL(dataObj.getString("DISCL")); + dataItem.setDiscR(dataObj.getString("DISCR")); + dataItem.setVibL(dataObj.getString("VIBL")); + dataItem.setVibR(dataObj.getString("VIBR")); + dataItem.setTime(dataObj.getString("UPTIME")); + + dataItemList.add(dataItem); + } + } + + @Override + public List toDataModelList() { + List dataList = new ArrayList<>(); + for (DataItem dataItem : dataItemList) { + DataMonitorPipeOther data = new DataMonitorPipeOther(); + + data.setDevcode(getDeviceCode()); + data.setLeftLength(((DataItemNCX)dataItem).getLenL()); + data.setRightLength(((DataItemNCX)dataItem).getLenR()); + data.setLeftGas(((DataItemNCX)dataItem).getCh4L()); + data.setRightGas(((DataItemNCX)dataItem).getCh4R()); + data.setVbat(((DataItemNCX)dataItem).getBat()); + data.setPipeInclineAlarm(((DataItemNCX)dataItem).getSlope()); + data.setPipeBreakAlarm(((DataItemNCX)dataItem).getDestroy()); + data.setGasAlarm(((DataItemNCX)dataItem).getLeak()); + data.setLeftOfflineAlarm(((DataItemNCX)dataItem).getDiscL()); + data.setRightOfflineAlarm(((DataItemNCX)dataItem).getDiscR()); + data.setLeftVibrateAlarm(((DataItemNCX)dataItem).getVibL()); + data.setRightVibrateAlarm(((DataItemNCX)dataItem).getVibR()); + data.setUptime(LocalDateTime.parse(((DataItemNCX)dataItem).getTime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 采集时间 + data.setLogtime(LocalDateTime.parse(getUptime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 上报时间 + + dataList.add(data); + } + + return dataList; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java new file mode 100644 index 0000000..372ac73 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java @@ -0,0 +1,31 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.DataItem; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class DataItemNCX extends DataItem { + String lenL; // 左侧指示带长度 + String lenR; // 右侧指示带长度 + String ch4L; // 左侧甲烷浓度值 + String ch4R; // 右侧甲烷浓度值 + String bat; // 电池电压 + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String spare; // 备用 + String time; // 采集时间 + + @Override + public String toString() { + return "气体浓度值:" + "(" + ch4L + "," + ch4R + ")" + "%LEL;" + + "电池电压值:" + bat + "v;" + + "采样时间:" + time; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java new file mode 100644 index 0000000..b3bbcf4 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java @@ -0,0 +1,43 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.EventFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class EventFrameNCX extends EventFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + eventItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + EventItemNCX eventItem = new EventItemNCX(); + + eventItem.setSlope(dataObj.getString("SLOPING")); + eventItem.setDestroy(dataObj.getString("DESTROY")); + eventItem.setLeak(dataObj.getString("LEAK")); + eventItem.setDiscL(dataObj.getString("DISCL")); + eventItem.setDiscR(dataObj.getString("DISCR")); + eventItem.setVibL(dataObj.getString("VIBL")); + eventItem.setVibR(dataObj.getString("VIBR")); + eventItem.setTime(dataObj.getString("UPTIME")); + + eventItemList.add(eventItem); + } + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java new file mode 100644 index 0000000..1a560d0 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java @@ -0,0 +1,49 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.EventItem; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.commons.lang3.StringUtils; + +@EqualsAndHashCode(callSuper = true) +@Data +public class EventItemNCX extends EventItem { + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String time; // 采集时间 + + @Override + public String toString() { + String str = ""; + if (StringUtils.isNotBlank(slope) && slope.equalsIgnoreCase("1")) { + str += "[倾斜报警]"; + } + if (StringUtils.isNotBlank(destroy) && destroy.equalsIgnoreCase("1")) { + str += "[破坏报警]"; + } + if (StringUtils.isNotBlank(leak) && leak.equalsIgnoreCase("1")) { + str += "[甲烷泄漏报警]"; + } + if (StringUtils.isNotBlank(discL) && discL.equalsIgnoreCase("1")) { + str += "[左侧断线报警]"; + } + if (StringUtils.isNotBlank(discR) && discR.equalsIgnoreCase("1")) { + str += "[右侧断线报警]"; + } + if (StringUtils.isNotBlank(vibL) && vibL.equalsIgnoreCase("1")) { + str += "[左侧振动报警]"; + } + if (StringUtils.isNotBlank(vibR) && vibR.equalsIgnoreCase("1")) { + str += "[右侧振动报警]"; + } + str += "采样时间:" + time; + + return str; + + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java new file mode 100644 index 0000000..343c4d6 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java @@ -0,0 +1,37 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class InfoFrameNCX extends CasicFrame { + + String workMode; + String model; + String hwVersion; + String softVersion; + String sensorType; + + @Override + public String toString() { + return "设备编号: " + getDeviceCode() + "; " + + "设备工作模式: " + workMode + " ; " + + "设备型号: " + model + " ; " + + "版本号: " + hwVersion + ", " + softVersion + "; " + + "传感器类型: " + sensorType + " ; " + + "上报时间: " + getUptime(); + } + + @Override + public void parseMessageBody() { + workMode = getMessageBody().getString("WORKMODE"); + model = getMessageBody().getString("MODEL"); + hwVersion = getMessageBody().getString("HWVERSION"); + softVersion = getMessageBody().getString("SOFTVERSION"); + sensorType = getMessageBody().getString("SENSORTYPE"); + } +} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java new file mode 100644 index 0000000..95d2bd4 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java @@ -0,0 +1,8 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.DataMonitorPipeOther; + +public interface IDataSentinelOtherService extends IService { + +} diff --git a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java index d6b1200..0290829 100644 --- a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java +++ b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java @@ -1,7 +1,6 @@ package com.casic.dao.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.dao.model.DataTubeOther; import com.casic.dao.model.DeviceWellView; public interface IDeviceWellViewService extends IService { diff --git a/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java new file mode 100644 index 0000000..be34f77 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java @@ -0,0 +1,16 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.BusDeviceMapper; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import org.springframework.stereotype.Service; + +@Service +public class BusDeviceServiceImpl extends ServiceImpl implements IBusDeviceService { + + @Override + public BusDevice getDeviceByCode(String devCode) { + return baseMapper.getOneByDevCode(devCode); + } +} diff --git a/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java new file mode 100644 index 0000000..0db2007 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java @@ -0,0 +1,11 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.DataSentinelOtherMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.service.IDataSentinelOtherService; +import org.springframework.stereotype.Service; + +@Service +public class DataSentinelOtherServiceImpl extends ServiceImpl implements IDataSentinelOtherService { +} diff --git a/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java new file mode 100644 index 0000000..d8c5ef2 --- /dev/null +++ b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java @@ -0,0 +1,111 @@ +package com.casic.protocol; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.CasicProtocol; +import org.springframework.stereotype.Component; + +@Component +public class CasicTubeProtocolImpl implements CasicProtocol { + @Override + public boolean checkFrame(String frame) { + boolean valid = checkFrameHeaderAndTail(frame); + if (valid) { + valid = checkFrameLength(frame); + } + + return valid; + } + + private boolean checkFrameHeaderAndTail(String frame) { + return (frame.substring(0, 2).equalsIgnoreCase("AA")) && + (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); + } + + private boolean checkFrameLength(String frame) { + String lengthStr = frame.substring(4, 7); + int length = Integer.parseInt(lengthStr); + + return frame.length() == length + 9; + } + + @Override + public String getDeviceType(String frame) { + return frame.substring(7, 9); + } + + @Override + public String getDeviceId(String frame) { + return frame.substring(9, 21); + } + + @Override + public String getManufacturerCode(String frame) { + return frame.substring(11, 13); + } + + @Override + public String getMessageType(String frame) { + return frame.substring(21, 23); + } + + @Override + public String getMessageSequence(String frame) { + return frame.substring(23, 25); + } + + @Override + public String getMessageBody(String frame) { + return frame.substring(26, frame.length() - 16); + } + + @Override + public JSONObject parseMessageBody(String messageBody) { + return JSONObject.parseObject(messageBody); + } + + @Override + public String getUptime(String frame) { + return frame.substring(frame.length() - 16, frame.length() - 2); + } + + @Override + public String buildFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append(frame.getMessageBody().toJSONString()); + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } + + @Override + public String buildReplyFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append("00"); // 消息响应类消息 消息体为00 + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/senitnel/controller/SentinelDataController.java b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java new file mode 100644 index 0000000..633c072 --- /dev/null +++ b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java @@ -0,0 +1,120 @@ +package com.casic.senitnel.controller; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.general.ConfigFrame; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import com.casic.senitnel.service.ISentinelFrameService; +import com.casic.util.aep.AepCommandSend; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Base64; +import java.util.Map; + +@Slf4j +@RestController +public class SentinelDataController { + + @Resource + private ISentinelFrameService frameService; + + @Resource + private IBusDeviceService deviceService; + + @RequestMapping("/sentinel/data/recv") + public Object dataRecv(@RequestBody Map map) { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + + JSONObject recvObj = (JSONObject) JSONObject.toJSON(map); + if (recvObj.containsKey("payload")) { + JSONObject payload = recvObj.getJSONObject("payload"); + String value = payload.getString("APPdata"); + + if (value.isEmpty()) { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } else { + byte[] baseBytes = Base64.getDecoder().decode(value); + String frameStr = new String(baseBytes); + + // 根据协议进行解析 + CasicFrame frame = frameService.dataParse(frameStr); + + if (frame != null) { + // 回复响应 + String replyFrameStr = frameService.replyMessage(frame.getDeviceCode(), frame.getSequence()); + + // 从数据库中获取master-api-key 回复响应消息 + BusDevice device = deviceService.getDeviceByCode(frame.getDeviceCode()); + if (device != null && StringUtils.isNotBlank(device.getMasterApiKey())) { + String masterApiKey = device.getMasterApiKey(); + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + + try { + int code = aepCommandSend.handleAndReply(replyFrameStr); + } catch (Exception ex) { + log.error("向设备回复响应异常:{}", ex.getMessage()); + } + } + + // 存库 + frameService.afterAction(frame); + } + + retObj.put("code", 200); + retObj.put("success", true); + } + } else { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } + + return retObj; + } + + @RequestMapping("/sentinel/config/send") + public Object configSend(@RequestBody Map map) throws Exception { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + CasicFrame cmdFrame = new ConfigFrame(); + cmdFrame.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + cmdFrame.setDeviceCode((String) map.get("devCode")); + cmdFrame.setSequence("01"); + cmdFrame.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + JSONObject messageBody = new JSONObject(); + messageBody.put("datas", map.get("cmdList")); + cmdFrame.setMessageBody(messageBody); + + String frameStr = frameService.doBuildCommand(cmdFrame); + + // TODO-LIST + // 这三个参数根据设备编号从数据库中取 + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + String masterApiKey = (String) map.get("masterApiKey"); + + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + int code = aepCommandSend.handleAndReply(frameStr); + + retObj.put("code", 200); + retObj.put("success", true); + retObj.put("AEPRetCode", code); + return retObj; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java new file mode 100644 index 0000000..368af03 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java @@ -0,0 +1,82 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; +import com.casic.dao.model.DataMonitorPipeOther; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class DataFrameNCX extends DataFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + dataItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + DataItemNCX dataItem = new DataItemNCX(); + + dataItem.setLenL(dataObj.getString("LENGL")); + dataItem.setLenR(dataObj.getString("LENGR")); + dataItem.setBat(dataObj.getString("BAT")); + dataItem.setCh4L(dataObj.getString("CH4L")); + dataItem.setCh4R(dataObj.getString("CH4R")); + dataItem.setSlope(dataObj.getString("SLOPING")); + dataItem.setDestroy(dataObj.getString("DESTROY")); + dataItem.setLeak(dataObj.getString("LEAK")); + dataItem.setDiscL(dataObj.getString("DISCL")); + dataItem.setDiscR(dataObj.getString("DISCR")); + dataItem.setVibL(dataObj.getString("VIBL")); + dataItem.setVibR(dataObj.getString("VIBR")); + dataItem.setTime(dataObj.getString("UPTIME")); + + dataItemList.add(dataItem); + } + } + + @Override + public List toDataModelList() { + List dataList = new ArrayList<>(); + for (DataItem dataItem : dataItemList) { + DataMonitorPipeOther data = new DataMonitorPipeOther(); + + data.setDevcode(getDeviceCode()); + data.setLeftLength(((DataItemNCX)dataItem).getLenL()); + data.setRightLength(((DataItemNCX)dataItem).getLenR()); + data.setLeftGas(((DataItemNCX)dataItem).getCh4L()); + data.setRightGas(((DataItemNCX)dataItem).getCh4R()); + data.setVbat(((DataItemNCX)dataItem).getBat()); + data.setPipeInclineAlarm(((DataItemNCX)dataItem).getSlope()); + data.setPipeBreakAlarm(((DataItemNCX)dataItem).getDestroy()); + data.setGasAlarm(((DataItemNCX)dataItem).getLeak()); + data.setLeftOfflineAlarm(((DataItemNCX)dataItem).getDiscL()); + data.setRightOfflineAlarm(((DataItemNCX)dataItem).getDiscR()); + data.setLeftVibrateAlarm(((DataItemNCX)dataItem).getVibL()); + data.setRightVibrateAlarm(((DataItemNCX)dataItem).getVibR()); + data.setUptime(LocalDateTime.parse(((DataItemNCX)dataItem).getTime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 采集时间 + data.setLogtime(LocalDateTime.parse(getUptime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 上报时间 + + dataList.add(data); + } + + return dataList; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java new file mode 100644 index 0000000..372ac73 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java @@ -0,0 +1,31 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.DataItem; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class DataItemNCX extends DataItem { + String lenL; // 左侧指示带长度 + String lenR; // 右侧指示带长度 + String ch4L; // 左侧甲烷浓度值 + String ch4R; // 右侧甲烷浓度值 + String bat; // 电池电压 + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String spare; // 备用 + String time; // 采集时间 + + @Override + public String toString() { + return "气体浓度值:" + "(" + ch4L + "," + ch4R + ")" + "%LEL;" + + "电池电压值:" + bat + "v;" + + "采样时间:" + time; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java new file mode 100644 index 0000000..b3bbcf4 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java @@ -0,0 +1,43 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.EventFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class EventFrameNCX extends EventFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + eventItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + EventItemNCX eventItem = new EventItemNCX(); + + eventItem.setSlope(dataObj.getString("SLOPING")); + eventItem.setDestroy(dataObj.getString("DESTROY")); + eventItem.setLeak(dataObj.getString("LEAK")); + eventItem.setDiscL(dataObj.getString("DISCL")); + eventItem.setDiscR(dataObj.getString("DISCR")); + eventItem.setVibL(dataObj.getString("VIBL")); + eventItem.setVibR(dataObj.getString("VIBR")); + eventItem.setTime(dataObj.getString("UPTIME")); + + eventItemList.add(eventItem); + } + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java new file mode 100644 index 0000000..1a560d0 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java @@ -0,0 +1,49 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.EventItem; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.commons.lang3.StringUtils; + +@EqualsAndHashCode(callSuper = true) +@Data +public class EventItemNCX extends EventItem { + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String time; // 采集时间 + + @Override + public String toString() { + String str = ""; + if (StringUtils.isNotBlank(slope) && slope.equalsIgnoreCase("1")) { + str += "[倾斜报警]"; + } + if (StringUtils.isNotBlank(destroy) && destroy.equalsIgnoreCase("1")) { + str += "[破坏报警]"; + } + if (StringUtils.isNotBlank(leak) && leak.equalsIgnoreCase("1")) { + str += "[甲烷泄漏报警]"; + } + if (StringUtils.isNotBlank(discL) && discL.equalsIgnoreCase("1")) { + str += "[左侧断线报警]"; + } + if (StringUtils.isNotBlank(discR) && discR.equalsIgnoreCase("1")) { + str += "[右侧断线报警]"; + } + if (StringUtils.isNotBlank(vibL) && vibL.equalsIgnoreCase("1")) { + str += "[左侧振动报警]"; + } + if (StringUtils.isNotBlank(vibR) && vibR.equalsIgnoreCase("1")) { + str += "[右侧振动报警]"; + } + str += "采样时间:" + time; + + return str; + + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java new file mode 100644 index 0000000..343c4d6 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java @@ -0,0 +1,37 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class InfoFrameNCX extends CasicFrame { + + String workMode; + String model; + String hwVersion; + String softVersion; + String sensorType; + + @Override + public String toString() { + return "设备编号: " + getDeviceCode() + "; " + + "设备工作模式: " + workMode + " ; " + + "设备型号: " + model + " ; " + + "版本号: " + hwVersion + ", " + softVersion + "; " + + "传感器类型: " + sensorType + " ; " + + "上报时间: " + getUptime(); + } + + @Override + public void parseMessageBody() { + workMode = getMessageBody().getString("WORKMODE"); + model = getMessageBody().getString("MODEL"); + hwVersion = getMessageBody().getString("HWVERSION"); + softVersion = getMessageBody().getString("SOFTVERSION"); + sensorType = getMessageBody().getString("SENSORTYPE"); + } +} diff --git a/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java new file mode 100644 index 0000000..e76fc86 --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java @@ -0,0 +1,14 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; + +public interface ISentinelFrameService { + + CasicFrame dataParse(String frame); + + String replyMessage(String deviceCode, String sequence); + + String doBuildCommand(CasicFrame cmd); + + void afterAction(CasicFrame frame); +} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java new file mode 100644 index 0000000..95d2bd4 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java @@ -0,0 +1,8 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.DataMonitorPipeOther; + +public interface IDataSentinelOtherService extends IService { + +} diff --git a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java index d6b1200..0290829 100644 --- a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java +++ b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java @@ -1,7 +1,6 @@ package com.casic.dao.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.dao.model.DataTubeOther; import com.casic.dao.model.DeviceWellView; public interface IDeviceWellViewService extends IService { diff --git a/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java new file mode 100644 index 0000000..be34f77 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java @@ -0,0 +1,16 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.BusDeviceMapper; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import org.springframework.stereotype.Service; + +@Service +public class BusDeviceServiceImpl extends ServiceImpl implements IBusDeviceService { + + @Override + public BusDevice getDeviceByCode(String devCode) { + return baseMapper.getOneByDevCode(devCode); + } +} diff --git a/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java new file mode 100644 index 0000000..0db2007 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java @@ -0,0 +1,11 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.DataSentinelOtherMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.service.IDataSentinelOtherService; +import org.springframework.stereotype.Service; + +@Service +public class DataSentinelOtherServiceImpl extends ServiceImpl implements IDataSentinelOtherService { +} diff --git a/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java new file mode 100644 index 0000000..d8c5ef2 --- /dev/null +++ b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java @@ -0,0 +1,111 @@ +package com.casic.protocol; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.CasicProtocol; +import org.springframework.stereotype.Component; + +@Component +public class CasicTubeProtocolImpl implements CasicProtocol { + @Override + public boolean checkFrame(String frame) { + boolean valid = checkFrameHeaderAndTail(frame); + if (valid) { + valid = checkFrameLength(frame); + } + + return valid; + } + + private boolean checkFrameHeaderAndTail(String frame) { + return (frame.substring(0, 2).equalsIgnoreCase("AA")) && + (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); + } + + private boolean checkFrameLength(String frame) { + String lengthStr = frame.substring(4, 7); + int length = Integer.parseInt(lengthStr); + + return frame.length() == length + 9; + } + + @Override + public String getDeviceType(String frame) { + return frame.substring(7, 9); + } + + @Override + public String getDeviceId(String frame) { + return frame.substring(9, 21); + } + + @Override + public String getManufacturerCode(String frame) { + return frame.substring(11, 13); + } + + @Override + public String getMessageType(String frame) { + return frame.substring(21, 23); + } + + @Override + public String getMessageSequence(String frame) { + return frame.substring(23, 25); + } + + @Override + public String getMessageBody(String frame) { + return frame.substring(26, frame.length() - 16); + } + + @Override + public JSONObject parseMessageBody(String messageBody) { + return JSONObject.parseObject(messageBody); + } + + @Override + public String getUptime(String frame) { + return frame.substring(frame.length() - 16, frame.length() - 2); + } + + @Override + public String buildFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append(frame.getMessageBody().toJSONString()); + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } + + @Override + public String buildReplyFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append("00"); // 消息响应类消息 消息体为00 + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/senitnel/controller/SentinelDataController.java b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java new file mode 100644 index 0000000..633c072 --- /dev/null +++ b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java @@ -0,0 +1,120 @@ +package com.casic.senitnel.controller; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.general.ConfigFrame; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import com.casic.senitnel.service.ISentinelFrameService; +import com.casic.util.aep.AepCommandSend; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Base64; +import java.util.Map; + +@Slf4j +@RestController +public class SentinelDataController { + + @Resource + private ISentinelFrameService frameService; + + @Resource + private IBusDeviceService deviceService; + + @RequestMapping("/sentinel/data/recv") + public Object dataRecv(@RequestBody Map map) { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + + JSONObject recvObj = (JSONObject) JSONObject.toJSON(map); + if (recvObj.containsKey("payload")) { + JSONObject payload = recvObj.getJSONObject("payload"); + String value = payload.getString("APPdata"); + + if (value.isEmpty()) { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } else { + byte[] baseBytes = Base64.getDecoder().decode(value); + String frameStr = new String(baseBytes); + + // 根据协议进行解析 + CasicFrame frame = frameService.dataParse(frameStr); + + if (frame != null) { + // 回复响应 + String replyFrameStr = frameService.replyMessage(frame.getDeviceCode(), frame.getSequence()); + + // 从数据库中获取master-api-key 回复响应消息 + BusDevice device = deviceService.getDeviceByCode(frame.getDeviceCode()); + if (device != null && StringUtils.isNotBlank(device.getMasterApiKey())) { + String masterApiKey = device.getMasterApiKey(); + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + + try { + int code = aepCommandSend.handleAndReply(replyFrameStr); + } catch (Exception ex) { + log.error("向设备回复响应异常:{}", ex.getMessage()); + } + } + + // 存库 + frameService.afterAction(frame); + } + + retObj.put("code", 200); + retObj.put("success", true); + } + } else { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } + + return retObj; + } + + @RequestMapping("/sentinel/config/send") + public Object configSend(@RequestBody Map map) throws Exception { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + CasicFrame cmdFrame = new ConfigFrame(); + cmdFrame.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + cmdFrame.setDeviceCode((String) map.get("devCode")); + cmdFrame.setSequence("01"); + cmdFrame.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + JSONObject messageBody = new JSONObject(); + messageBody.put("datas", map.get("cmdList")); + cmdFrame.setMessageBody(messageBody); + + String frameStr = frameService.doBuildCommand(cmdFrame); + + // TODO-LIST + // 这三个参数根据设备编号从数据库中取 + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + String masterApiKey = (String) map.get("masterApiKey"); + + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + int code = aepCommandSend.handleAndReply(frameStr); + + retObj.put("code", 200); + retObj.put("success", true); + retObj.put("AEPRetCode", code); + return retObj; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java new file mode 100644 index 0000000..368af03 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java @@ -0,0 +1,82 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; +import com.casic.dao.model.DataMonitorPipeOther; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class DataFrameNCX extends DataFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + dataItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + DataItemNCX dataItem = new DataItemNCX(); + + dataItem.setLenL(dataObj.getString("LENGL")); + dataItem.setLenR(dataObj.getString("LENGR")); + dataItem.setBat(dataObj.getString("BAT")); + dataItem.setCh4L(dataObj.getString("CH4L")); + dataItem.setCh4R(dataObj.getString("CH4R")); + dataItem.setSlope(dataObj.getString("SLOPING")); + dataItem.setDestroy(dataObj.getString("DESTROY")); + dataItem.setLeak(dataObj.getString("LEAK")); + dataItem.setDiscL(dataObj.getString("DISCL")); + dataItem.setDiscR(dataObj.getString("DISCR")); + dataItem.setVibL(dataObj.getString("VIBL")); + dataItem.setVibR(dataObj.getString("VIBR")); + dataItem.setTime(dataObj.getString("UPTIME")); + + dataItemList.add(dataItem); + } + } + + @Override + public List toDataModelList() { + List dataList = new ArrayList<>(); + for (DataItem dataItem : dataItemList) { + DataMonitorPipeOther data = new DataMonitorPipeOther(); + + data.setDevcode(getDeviceCode()); + data.setLeftLength(((DataItemNCX)dataItem).getLenL()); + data.setRightLength(((DataItemNCX)dataItem).getLenR()); + data.setLeftGas(((DataItemNCX)dataItem).getCh4L()); + data.setRightGas(((DataItemNCX)dataItem).getCh4R()); + data.setVbat(((DataItemNCX)dataItem).getBat()); + data.setPipeInclineAlarm(((DataItemNCX)dataItem).getSlope()); + data.setPipeBreakAlarm(((DataItemNCX)dataItem).getDestroy()); + data.setGasAlarm(((DataItemNCX)dataItem).getLeak()); + data.setLeftOfflineAlarm(((DataItemNCX)dataItem).getDiscL()); + data.setRightOfflineAlarm(((DataItemNCX)dataItem).getDiscR()); + data.setLeftVibrateAlarm(((DataItemNCX)dataItem).getVibL()); + data.setRightVibrateAlarm(((DataItemNCX)dataItem).getVibR()); + data.setUptime(LocalDateTime.parse(((DataItemNCX)dataItem).getTime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 采集时间 + data.setLogtime(LocalDateTime.parse(getUptime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 上报时间 + + dataList.add(data); + } + + return dataList; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java new file mode 100644 index 0000000..372ac73 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java @@ -0,0 +1,31 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.DataItem; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class DataItemNCX extends DataItem { + String lenL; // 左侧指示带长度 + String lenR; // 右侧指示带长度 + String ch4L; // 左侧甲烷浓度值 + String ch4R; // 右侧甲烷浓度值 + String bat; // 电池电压 + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String spare; // 备用 + String time; // 采集时间 + + @Override + public String toString() { + return "气体浓度值:" + "(" + ch4L + "," + ch4R + ")" + "%LEL;" + + "电池电压值:" + bat + "v;" + + "采样时间:" + time; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java new file mode 100644 index 0000000..b3bbcf4 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java @@ -0,0 +1,43 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.EventFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class EventFrameNCX extends EventFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + eventItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + EventItemNCX eventItem = new EventItemNCX(); + + eventItem.setSlope(dataObj.getString("SLOPING")); + eventItem.setDestroy(dataObj.getString("DESTROY")); + eventItem.setLeak(dataObj.getString("LEAK")); + eventItem.setDiscL(dataObj.getString("DISCL")); + eventItem.setDiscR(dataObj.getString("DISCR")); + eventItem.setVibL(dataObj.getString("VIBL")); + eventItem.setVibR(dataObj.getString("VIBR")); + eventItem.setTime(dataObj.getString("UPTIME")); + + eventItemList.add(eventItem); + } + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java new file mode 100644 index 0000000..1a560d0 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java @@ -0,0 +1,49 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.EventItem; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.commons.lang3.StringUtils; + +@EqualsAndHashCode(callSuper = true) +@Data +public class EventItemNCX extends EventItem { + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String time; // 采集时间 + + @Override + public String toString() { + String str = ""; + if (StringUtils.isNotBlank(slope) && slope.equalsIgnoreCase("1")) { + str += "[倾斜报警]"; + } + if (StringUtils.isNotBlank(destroy) && destroy.equalsIgnoreCase("1")) { + str += "[破坏报警]"; + } + if (StringUtils.isNotBlank(leak) && leak.equalsIgnoreCase("1")) { + str += "[甲烷泄漏报警]"; + } + if (StringUtils.isNotBlank(discL) && discL.equalsIgnoreCase("1")) { + str += "[左侧断线报警]"; + } + if (StringUtils.isNotBlank(discR) && discR.equalsIgnoreCase("1")) { + str += "[右侧断线报警]"; + } + if (StringUtils.isNotBlank(vibL) && vibL.equalsIgnoreCase("1")) { + str += "[左侧振动报警]"; + } + if (StringUtils.isNotBlank(vibR) && vibR.equalsIgnoreCase("1")) { + str += "[右侧振动报警]"; + } + str += "采样时间:" + time; + + return str; + + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java new file mode 100644 index 0000000..343c4d6 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java @@ -0,0 +1,37 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class InfoFrameNCX extends CasicFrame { + + String workMode; + String model; + String hwVersion; + String softVersion; + String sensorType; + + @Override + public String toString() { + return "设备编号: " + getDeviceCode() + "; " + + "设备工作模式: " + workMode + " ; " + + "设备型号: " + model + " ; " + + "版本号: " + hwVersion + ", " + softVersion + "; " + + "传感器类型: " + sensorType + " ; " + + "上报时间: " + getUptime(); + } + + @Override + public void parseMessageBody() { + workMode = getMessageBody().getString("WORKMODE"); + model = getMessageBody().getString("MODEL"); + hwVersion = getMessageBody().getString("HWVERSION"); + softVersion = getMessageBody().getString("SOFTVERSION"); + sensorType = getMessageBody().getString("SENSORTYPE"); + } +} diff --git a/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java new file mode 100644 index 0000000..e76fc86 --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java @@ -0,0 +1,14 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; + +public interface ISentinelFrameService { + + CasicFrame dataParse(String frame); + + String replyMessage(String deviceCode, String sequence); + + String doBuildCommand(CasicFrame cmd); + + void afterAction(CasicFrame frame); +} diff --git a/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java new file mode 100644 index 0000000..803ff0e --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java @@ -0,0 +1,109 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; +import com.casic.common.CasicFrameBuildFactory; +import com.casic.common.CasicProtocol; +import com.casic.common.general.DataFrame; +import com.casic.common.general.EventFrame; +import com.casic.common.general.ReplyFrame; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.model.DeviceWellView; +import com.casic.dao.service.IDataSentinelOtherService; +import com.casic.dao.service.IDeviceWellViewService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + + +@Service +@Slf4j +public class SentinelFrameServiceImpl implements ISentinelFrameService { + + @Resource + private CasicProtocol protocol; + + @Resource + IDataSentinelOtherService sentinelDataService; + + @Resource + IDeviceWellViewService deviceService; + + public CasicFrame dataParse(String frame) { + // 1. 判断帧结构 + boolean frameValid = protocol.checkFrame(frame); + if (frameValid) { + // 2. 获取帧结构中的关键字段信息 + String deviceId = protocol.getDeviceId(frame); + String deviceType = protocol.getDeviceType(frame); + String messageType = protocol.getMessageType(frame); + String messageBody = protocol.getMessageBody(frame).toUpperCase(); + String uptime = protocol.getUptime(frame); + String sequence = protocol.getMessageSequence(frame); + + String manufacturerCode = protocol.getManufacturerCode(frame); + CasicFrame sentinelFrame = CasicFrameBuildFactory.buildCasicFrame(messageType, manufacturerCode, deviceType); + + if (sentinelFrame != null) { + sentinelFrame.setDeviceCode(deviceId); + sentinelFrame.setUptime(uptime); + sentinelFrame.setMessageType(messageType); + sentinelFrame.setSequence(sequence); + + // 心跳类的消息不解析MessageBody + if (!sentinelFrame.getMessageType().equals("00")) { + sentinelFrame.setMessageBody(protocol.parseMessageBody(messageBody)); + sentinelFrame.parseMessageBody(); + } + + log.info("收到设备消息:{}", sentinelFrame); + return sentinelFrame; + } + } else { + log.error("消息帧解析异常"); + } + + return null; + } + + @Override + public String replyMessage(String deviceCode, String sequence) { + CasicFrame reply = new ReplyFrame(); + reply.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + reply.setDeviceCode(deviceCode); + reply.setSequence(sequence); + reply.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + return protocol.buildReplyFrameStr(reply); + } + + @Override + public String doBuildCommand(CasicFrame cmd) { + return protocol.buildFrameStr(cmd); + } + + @Override + public void afterAction(CasicFrame frame) { + // 数据消息帧 进行存库操作 + if (frame instanceof DataFrame) { + String devCode = frame.getDeviceCode(); + DeviceWellView devWellView = deviceService.getDeviceWellViewByDevCode(devCode); + String wellCode = ""; + if (devWellView != null) { + wellCode = devWellView.getWellCode(); + } + List dataList = ((DataFrame) frame).toDataModelList(); + if (dataList != null) { + for (Serializable item : dataList) { + DataMonitorPipeOther data = (DataMonitorPipeOther) item; + data.setWellCode(wellCode); + sentinelDataService.save(data); + } + } + } + } +} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java new file mode 100644 index 0000000..95d2bd4 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java @@ -0,0 +1,8 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.DataMonitorPipeOther; + +public interface IDataSentinelOtherService extends IService { + +} diff --git a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java index d6b1200..0290829 100644 --- a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java +++ b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java @@ -1,7 +1,6 @@ package com.casic.dao.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.dao.model.DataTubeOther; import com.casic.dao.model.DeviceWellView; public interface IDeviceWellViewService extends IService { diff --git a/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java new file mode 100644 index 0000000..be34f77 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java @@ -0,0 +1,16 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.BusDeviceMapper; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import org.springframework.stereotype.Service; + +@Service +public class BusDeviceServiceImpl extends ServiceImpl implements IBusDeviceService { + + @Override + public BusDevice getDeviceByCode(String devCode) { + return baseMapper.getOneByDevCode(devCode); + } +} diff --git a/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java new file mode 100644 index 0000000..0db2007 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java @@ -0,0 +1,11 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.DataSentinelOtherMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.service.IDataSentinelOtherService; +import org.springframework.stereotype.Service; + +@Service +public class DataSentinelOtherServiceImpl extends ServiceImpl implements IDataSentinelOtherService { +} diff --git a/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java new file mode 100644 index 0000000..d8c5ef2 --- /dev/null +++ b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java @@ -0,0 +1,111 @@ +package com.casic.protocol; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.CasicProtocol; +import org.springframework.stereotype.Component; + +@Component +public class CasicTubeProtocolImpl implements CasicProtocol { + @Override + public boolean checkFrame(String frame) { + boolean valid = checkFrameHeaderAndTail(frame); + if (valid) { + valid = checkFrameLength(frame); + } + + return valid; + } + + private boolean checkFrameHeaderAndTail(String frame) { + return (frame.substring(0, 2).equalsIgnoreCase("AA")) && + (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); + } + + private boolean checkFrameLength(String frame) { + String lengthStr = frame.substring(4, 7); + int length = Integer.parseInt(lengthStr); + + return frame.length() == length + 9; + } + + @Override + public String getDeviceType(String frame) { + return frame.substring(7, 9); + } + + @Override + public String getDeviceId(String frame) { + return frame.substring(9, 21); + } + + @Override + public String getManufacturerCode(String frame) { + return frame.substring(11, 13); + } + + @Override + public String getMessageType(String frame) { + return frame.substring(21, 23); + } + + @Override + public String getMessageSequence(String frame) { + return frame.substring(23, 25); + } + + @Override + public String getMessageBody(String frame) { + return frame.substring(26, frame.length() - 16); + } + + @Override + public JSONObject parseMessageBody(String messageBody) { + return JSONObject.parseObject(messageBody); + } + + @Override + public String getUptime(String frame) { + return frame.substring(frame.length() - 16, frame.length() - 2); + } + + @Override + public String buildFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append(frame.getMessageBody().toJSONString()); + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } + + @Override + public String buildReplyFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append("00"); // 消息响应类消息 消息体为00 + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/senitnel/controller/SentinelDataController.java b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java new file mode 100644 index 0000000..633c072 --- /dev/null +++ b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java @@ -0,0 +1,120 @@ +package com.casic.senitnel.controller; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.general.ConfigFrame; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import com.casic.senitnel.service.ISentinelFrameService; +import com.casic.util.aep.AepCommandSend; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Base64; +import java.util.Map; + +@Slf4j +@RestController +public class SentinelDataController { + + @Resource + private ISentinelFrameService frameService; + + @Resource + private IBusDeviceService deviceService; + + @RequestMapping("/sentinel/data/recv") + public Object dataRecv(@RequestBody Map map) { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + + JSONObject recvObj = (JSONObject) JSONObject.toJSON(map); + if (recvObj.containsKey("payload")) { + JSONObject payload = recvObj.getJSONObject("payload"); + String value = payload.getString("APPdata"); + + if (value.isEmpty()) { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } else { + byte[] baseBytes = Base64.getDecoder().decode(value); + String frameStr = new String(baseBytes); + + // 根据协议进行解析 + CasicFrame frame = frameService.dataParse(frameStr); + + if (frame != null) { + // 回复响应 + String replyFrameStr = frameService.replyMessage(frame.getDeviceCode(), frame.getSequence()); + + // 从数据库中获取master-api-key 回复响应消息 + BusDevice device = deviceService.getDeviceByCode(frame.getDeviceCode()); + if (device != null && StringUtils.isNotBlank(device.getMasterApiKey())) { + String masterApiKey = device.getMasterApiKey(); + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + + try { + int code = aepCommandSend.handleAndReply(replyFrameStr); + } catch (Exception ex) { + log.error("向设备回复响应异常:{}", ex.getMessage()); + } + } + + // 存库 + frameService.afterAction(frame); + } + + retObj.put("code", 200); + retObj.put("success", true); + } + } else { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } + + return retObj; + } + + @RequestMapping("/sentinel/config/send") + public Object configSend(@RequestBody Map map) throws Exception { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + CasicFrame cmdFrame = new ConfigFrame(); + cmdFrame.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + cmdFrame.setDeviceCode((String) map.get("devCode")); + cmdFrame.setSequence("01"); + cmdFrame.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + JSONObject messageBody = new JSONObject(); + messageBody.put("datas", map.get("cmdList")); + cmdFrame.setMessageBody(messageBody); + + String frameStr = frameService.doBuildCommand(cmdFrame); + + // TODO-LIST + // 这三个参数根据设备编号从数据库中取 + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + String masterApiKey = (String) map.get("masterApiKey"); + + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + int code = aepCommandSend.handleAndReply(frameStr); + + retObj.put("code", 200); + retObj.put("success", true); + retObj.put("AEPRetCode", code); + return retObj; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java new file mode 100644 index 0000000..368af03 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java @@ -0,0 +1,82 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; +import com.casic.dao.model.DataMonitorPipeOther; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class DataFrameNCX extends DataFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + dataItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + DataItemNCX dataItem = new DataItemNCX(); + + dataItem.setLenL(dataObj.getString("LENGL")); + dataItem.setLenR(dataObj.getString("LENGR")); + dataItem.setBat(dataObj.getString("BAT")); + dataItem.setCh4L(dataObj.getString("CH4L")); + dataItem.setCh4R(dataObj.getString("CH4R")); + dataItem.setSlope(dataObj.getString("SLOPING")); + dataItem.setDestroy(dataObj.getString("DESTROY")); + dataItem.setLeak(dataObj.getString("LEAK")); + dataItem.setDiscL(dataObj.getString("DISCL")); + dataItem.setDiscR(dataObj.getString("DISCR")); + dataItem.setVibL(dataObj.getString("VIBL")); + dataItem.setVibR(dataObj.getString("VIBR")); + dataItem.setTime(dataObj.getString("UPTIME")); + + dataItemList.add(dataItem); + } + } + + @Override + public List toDataModelList() { + List dataList = new ArrayList<>(); + for (DataItem dataItem : dataItemList) { + DataMonitorPipeOther data = new DataMonitorPipeOther(); + + data.setDevcode(getDeviceCode()); + data.setLeftLength(((DataItemNCX)dataItem).getLenL()); + data.setRightLength(((DataItemNCX)dataItem).getLenR()); + data.setLeftGas(((DataItemNCX)dataItem).getCh4L()); + data.setRightGas(((DataItemNCX)dataItem).getCh4R()); + data.setVbat(((DataItemNCX)dataItem).getBat()); + data.setPipeInclineAlarm(((DataItemNCX)dataItem).getSlope()); + data.setPipeBreakAlarm(((DataItemNCX)dataItem).getDestroy()); + data.setGasAlarm(((DataItemNCX)dataItem).getLeak()); + data.setLeftOfflineAlarm(((DataItemNCX)dataItem).getDiscL()); + data.setRightOfflineAlarm(((DataItemNCX)dataItem).getDiscR()); + data.setLeftVibrateAlarm(((DataItemNCX)dataItem).getVibL()); + data.setRightVibrateAlarm(((DataItemNCX)dataItem).getVibR()); + data.setUptime(LocalDateTime.parse(((DataItemNCX)dataItem).getTime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 采集时间 + data.setLogtime(LocalDateTime.parse(getUptime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 上报时间 + + dataList.add(data); + } + + return dataList; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java new file mode 100644 index 0000000..372ac73 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java @@ -0,0 +1,31 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.DataItem; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class DataItemNCX extends DataItem { + String lenL; // 左侧指示带长度 + String lenR; // 右侧指示带长度 + String ch4L; // 左侧甲烷浓度值 + String ch4R; // 右侧甲烷浓度值 + String bat; // 电池电压 + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String spare; // 备用 + String time; // 采集时间 + + @Override + public String toString() { + return "气体浓度值:" + "(" + ch4L + "," + ch4R + ")" + "%LEL;" + + "电池电压值:" + bat + "v;" + + "采样时间:" + time; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java new file mode 100644 index 0000000..b3bbcf4 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java @@ -0,0 +1,43 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.EventFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class EventFrameNCX extends EventFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + eventItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + EventItemNCX eventItem = new EventItemNCX(); + + eventItem.setSlope(dataObj.getString("SLOPING")); + eventItem.setDestroy(dataObj.getString("DESTROY")); + eventItem.setLeak(dataObj.getString("LEAK")); + eventItem.setDiscL(dataObj.getString("DISCL")); + eventItem.setDiscR(dataObj.getString("DISCR")); + eventItem.setVibL(dataObj.getString("VIBL")); + eventItem.setVibR(dataObj.getString("VIBR")); + eventItem.setTime(dataObj.getString("UPTIME")); + + eventItemList.add(eventItem); + } + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java new file mode 100644 index 0000000..1a560d0 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java @@ -0,0 +1,49 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.EventItem; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.commons.lang3.StringUtils; + +@EqualsAndHashCode(callSuper = true) +@Data +public class EventItemNCX extends EventItem { + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String time; // 采集时间 + + @Override + public String toString() { + String str = ""; + if (StringUtils.isNotBlank(slope) && slope.equalsIgnoreCase("1")) { + str += "[倾斜报警]"; + } + if (StringUtils.isNotBlank(destroy) && destroy.equalsIgnoreCase("1")) { + str += "[破坏报警]"; + } + if (StringUtils.isNotBlank(leak) && leak.equalsIgnoreCase("1")) { + str += "[甲烷泄漏报警]"; + } + if (StringUtils.isNotBlank(discL) && discL.equalsIgnoreCase("1")) { + str += "[左侧断线报警]"; + } + if (StringUtils.isNotBlank(discR) && discR.equalsIgnoreCase("1")) { + str += "[右侧断线报警]"; + } + if (StringUtils.isNotBlank(vibL) && vibL.equalsIgnoreCase("1")) { + str += "[左侧振动报警]"; + } + if (StringUtils.isNotBlank(vibR) && vibR.equalsIgnoreCase("1")) { + str += "[右侧振动报警]"; + } + str += "采样时间:" + time; + + return str; + + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java new file mode 100644 index 0000000..343c4d6 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java @@ -0,0 +1,37 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class InfoFrameNCX extends CasicFrame { + + String workMode; + String model; + String hwVersion; + String softVersion; + String sensorType; + + @Override + public String toString() { + return "设备编号: " + getDeviceCode() + "; " + + "设备工作模式: " + workMode + " ; " + + "设备型号: " + model + " ; " + + "版本号: " + hwVersion + ", " + softVersion + "; " + + "传感器类型: " + sensorType + " ; " + + "上报时间: " + getUptime(); + } + + @Override + public void parseMessageBody() { + workMode = getMessageBody().getString("WORKMODE"); + model = getMessageBody().getString("MODEL"); + hwVersion = getMessageBody().getString("HWVERSION"); + softVersion = getMessageBody().getString("SOFTVERSION"); + sensorType = getMessageBody().getString("SENSORTYPE"); + } +} diff --git a/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java new file mode 100644 index 0000000..e76fc86 --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java @@ -0,0 +1,14 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; + +public interface ISentinelFrameService { + + CasicFrame dataParse(String frame); + + String replyMessage(String deviceCode, String sequence); + + String doBuildCommand(CasicFrame cmd); + + void afterAction(CasicFrame frame); +} diff --git a/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java new file mode 100644 index 0000000..803ff0e --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java @@ -0,0 +1,109 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; +import com.casic.common.CasicFrameBuildFactory; +import com.casic.common.CasicProtocol; +import com.casic.common.general.DataFrame; +import com.casic.common.general.EventFrame; +import com.casic.common.general.ReplyFrame; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.model.DeviceWellView; +import com.casic.dao.service.IDataSentinelOtherService; +import com.casic.dao.service.IDeviceWellViewService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + + +@Service +@Slf4j +public class SentinelFrameServiceImpl implements ISentinelFrameService { + + @Resource + private CasicProtocol protocol; + + @Resource + IDataSentinelOtherService sentinelDataService; + + @Resource + IDeviceWellViewService deviceService; + + public CasicFrame dataParse(String frame) { + // 1. 判断帧结构 + boolean frameValid = protocol.checkFrame(frame); + if (frameValid) { + // 2. 获取帧结构中的关键字段信息 + String deviceId = protocol.getDeviceId(frame); + String deviceType = protocol.getDeviceType(frame); + String messageType = protocol.getMessageType(frame); + String messageBody = protocol.getMessageBody(frame).toUpperCase(); + String uptime = protocol.getUptime(frame); + String sequence = protocol.getMessageSequence(frame); + + String manufacturerCode = protocol.getManufacturerCode(frame); + CasicFrame sentinelFrame = CasicFrameBuildFactory.buildCasicFrame(messageType, manufacturerCode, deviceType); + + if (sentinelFrame != null) { + sentinelFrame.setDeviceCode(deviceId); + sentinelFrame.setUptime(uptime); + sentinelFrame.setMessageType(messageType); + sentinelFrame.setSequence(sequence); + + // 心跳类的消息不解析MessageBody + if (!sentinelFrame.getMessageType().equals("00")) { + sentinelFrame.setMessageBody(protocol.parseMessageBody(messageBody)); + sentinelFrame.parseMessageBody(); + } + + log.info("收到设备消息:{}", sentinelFrame); + return sentinelFrame; + } + } else { + log.error("消息帧解析异常"); + } + + return null; + } + + @Override + public String replyMessage(String deviceCode, String sequence) { + CasicFrame reply = new ReplyFrame(); + reply.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + reply.setDeviceCode(deviceCode); + reply.setSequence(sequence); + reply.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + return protocol.buildReplyFrameStr(reply); + } + + @Override + public String doBuildCommand(CasicFrame cmd) { + return protocol.buildFrameStr(cmd); + } + + @Override + public void afterAction(CasicFrame frame) { + // 数据消息帧 进行存库操作 + if (frame instanceof DataFrame) { + String devCode = frame.getDeviceCode(); + DeviceWellView devWellView = deviceService.getDeviceWellViewByDevCode(devCode); + String wellCode = ""; + if (devWellView != null) { + wellCode = devWellView.getWellCode(); + } + List dataList = ((DataFrame) frame).toDataModelList(); + if (dataList != null) { + for (Serializable item : dataList) { + DataMonitorPipeOther data = (DataMonitorPipeOther) item; + data.setWellCode(wellCode); + sentinelDataService.save(data); + } + } + } + } +} diff --git a/src/main/java/com/casic/tube/controller/TubeDataController.java b/src/main/java/com/casic/tube/controller/TubeDataController.java index 61486c5..4965449 100644 --- a/src/main/java/com/casic/tube/controller/TubeDataController.java +++ b/src/main/java/com/casic/tube/controller/TubeDataController.java @@ -2,8 +2,8 @@ import com.alibaba.fastjson.JSONObject; import com.casic.common.CasicFrame; -import com.casic.tube.frame.ConfigFrame; -import com.casic.tube.service.ITubeDataService; +import com.casic.common.general.ConfigFrame; +import com.casic.tube.service.ITubeFrameService; import com.casic.util.aep.AepCommandSend; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestBody; @@ -21,7 +21,7 @@ public class TubeDataController { @Resource - private ITubeDataService tubeDataService; + private ITubeFrameService frameService; @RequestMapping("/tube/data/recv") public Object dataRecv(@RequestBody Map map) { @@ -42,10 +42,10 @@ String frameStr = new String(baseBytes); // 根据协议进行解析 - CasicFrame frame = tubeDataService.dataParse(frameStr); + CasicFrame frame = frameService.dataParse(frameStr); // 存库 - tubeDataService.afterAction(frame); + frameService.afterAction(frame); retObj.put("code", 200); retObj.put("success", true); @@ -74,7 +74,7 @@ messageBody.put("datas", map.get("cmdList")); cmdFrame.setMessageBody(messageBody); - String frameStr = tubeDataService.doBuildCommand(cmdFrame); + String frameStr = frameService.doBuildCommand(cmdFrame); // TODO-LIST // 这三个参数根据设备编号从数据库中取 diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java new file mode 100644 index 0000000..95d2bd4 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java @@ -0,0 +1,8 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.DataMonitorPipeOther; + +public interface IDataSentinelOtherService extends IService { + +} diff --git a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java index d6b1200..0290829 100644 --- a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java +++ b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java @@ -1,7 +1,6 @@ package com.casic.dao.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.dao.model.DataTubeOther; import com.casic.dao.model.DeviceWellView; public interface IDeviceWellViewService extends IService { diff --git a/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java new file mode 100644 index 0000000..be34f77 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java @@ -0,0 +1,16 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.BusDeviceMapper; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import org.springframework.stereotype.Service; + +@Service +public class BusDeviceServiceImpl extends ServiceImpl implements IBusDeviceService { + + @Override + public BusDevice getDeviceByCode(String devCode) { + return baseMapper.getOneByDevCode(devCode); + } +} diff --git a/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java new file mode 100644 index 0000000..0db2007 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java @@ -0,0 +1,11 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.DataSentinelOtherMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.service.IDataSentinelOtherService; +import org.springframework.stereotype.Service; + +@Service +public class DataSentinelOtherServiceImpl extends ServiceImpl implements IDataSentinelOtherService { +} diff --git a/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java new file mode 100644 index 0000000..d8c5ef2 --- /dev/null +++ b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java @@ -0,0 +1,111 @@ +package com.casic.protocol; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.CasicProtocol; +import org.springframework.stereotype.Component; + +@Component +public class CasicTubeProtocolImpl implements CasicProtocol { + @Override + public boolean checkFrame(String frame) { + boolean valid = checkFrameHeaderAndTail(frame); + if (valid) { + valid = checkFrameLength(frame); + } + + return valid; + } + + private boolean checkFrameHeaderAndTail(String frame) { + return (frame.substring(0, 2).equalsIgnoreCase("AA")) && + (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); + } + + private boolean checkFrameLength(String frame) { + String lengthStr = frame.substring(4, 7); + int length = Integer.parseInt(lengthStr); + + return frame.length() == length + 9; + } + + @Override + public String getDeviceType(String frame) { + return frame.substring(7, 9); + } + + @Override + public String getDeviceId(String frame) { + return frame.substring(9, 21); + } + + @Override + public String getManufacturerCode(String frame) { + return frame.substring(11, 13); + } + + @Override + public String getMessageType(String frame) { + return frame.substring(21, 23); + } + + @Override + public String getMessageSequence(String frame) { + return frame.substring(23, 25); + } + + @Override + public String getMessageBody(String frame) { + return frame.substring(26, frame.length() - 16); + } + + @Override + public JSONObject parseMessageBody(String messageBody) { + return JSONObject.parseObject(messageBody); + } + + @Override + public String getUptime(String frame) { + return frame.substring(frame.length() - 16, frame.length() - 2); + } + + @Override + public String buildFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append(frame.getMessageBody().toJSONString()); + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } + + @Override + public String buildReplyFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append("00"); // 消息响应类消息 消息体为00 + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/senitnel/controller/SentinelDataController.java b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java new file mode 100644 index 0000000..633c072 --- /dev/null +++ b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java @@ -0,0 +1,120 @@ +package com.casic.senitnel.controller; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.general.ConfigFrame; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import com.casic.senitnel.service.ISentinelFrameService; +import com.casic.util.aep.AepCommandSend; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Base64; +import java.util.Map; + +@Slf4j +@RestController +public class SentinelDataController { + + @Resource + private ISentinelFrameService frameService; + + @Resource + private IBusDeviceService deviceService; + + @RequestMapping("/sentinel/data/recv") + public Object dataRecv(@RequestBody Map map) { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + + JSONObject recvObj = (JSONObject) JSONObject.toJSON(map); + if (recvObj.containsKey("payload")) { + JSONObject payload = recvObj.getJSONObject("payload"); + String value = payload.getString("APPdata"); + + if (value.isEmpty()) { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } else { + byte[] baseBytes = Base64.getDecoder().decode(value); + String frameStr = new String(baseBytes); + + // 根据协议进行解析 + CasicFrame frame = frameService.dataParse(frameStr); + + if (frame != null) { + // 回复响应 + String replyFrameStr = frameService.replyMessage(frame.getDeviceCode(), frame.getSequence()); + + // 从数据库中获取master-api-key 回复响应消息 + BusDevice device = deviceService.getDeviceByCode(frame.getDeviceCode()); + if (device != null && StringUtils.isNotBlank(device.getMasterApiKey())) { + String masterApiKey = device.getMasterApiKey(); + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + + try { + int code = aepCommandSend.handleAndReply(replyFrameStr); + } catch (Exception ex) { + log.error("向设备回复响应异常:{}", ex.getMessage()); + } + } + + // 存库 + frameService.afterAction(frame); + } + + retObj.put("code", 200); + retObj.put("success", true); + } + } else { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } + + return retObj; + } + + @RequestMapping("/sentinel/config/send") + public Object configSend(@RequestBody Map map) throws Exception { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + CasicFrame cmdFrame = new ConfigFrame(); + cmdFrame.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + cmdFrame.setDeviceCode((String) map.get("devCode")); + cmdFrame.setSequence("01"); + cmdFrame.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + JSONObject messageBody = new JSONObject(); + messageBody.put("datas", map.get("cmdList")); + cmdFrame.setMessageBody(messageBody); + + String frameStr = frameService.doBuildCommand(cmdFrame); + + // TODO-LIST + // 这三个参数根据设备编号从数据库中取 + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + String masterApiKey = (String) map.get("masterApiKey"); + + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + int code = aepCommandSend.handleAndReply(frameStr); + + retObj.put("code", 200); + retObj.put("success", true); + retObj.put("AEPRetCode", code); + return retObj; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java new file mode 100644 index 0000000..368af03 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java @@ -0,0 +1,82 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; +import com.casic.dao.model.DataMonitorPipeOther; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class DataFrameNCX extends DataFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + dataItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + DataItemNCX dataItem = new DataItemNCX(); + + dataItem.setLenL(dataObj.getString("LENGL")); + dataItem.setLenR(dataObj.getString("LENGR")); + dataItem.setBat(dataObj.getString("BAT")); + dataItem.setCh4L(dataObj.getString("CH4L")); + dataItem.setCh4R(dataObj.getString("CH4R")); + dataItem.setSlope(dataObj.getString("SLOPING")); + dataItem.setDestroy(dataObj.getString("DESTROY")); + dataItem.setLeak(dataObj.getString("LEAK")); + dataItem.setDiscL(dataObj.getString("DISCL")); + dataItem.setDiscR(dataObj.getString("DISCR")); + dataItem.setVibL(dataObj.getString("VIBL")); + dataItem.setVibR(dataObj.getString("VIBR")); + dataItem.setTime(dataObj.getString("UPTIME")); + + dataItemList.add(dataItem); + } + } + + @Override + public List toDataModelList() { + List dataList = new ArrayList<>(); + for (DataItem dataItem : dataItemList) { + DataMonitorPipeOther data = new DataMonitorPipeOther(); + + data.setDevcode(getDeviceCode()); + data.setLeftLength(((DataItemNCX)dataItem).getLenL()); + data.setRightLength(((DataItemNCX)dataItem).getLenR()); + data.setLeftGas(((DataItemNCX)dataItem).getCh4L()); + data.setRightGas(((DataItemNCX)dataItem).getCh4R()); + data.setVbat(((DataItemNCX)dataItem).getBat()); + data.setPipeInclineAlarm(((DataItemNCX)dataItem).getSlope()); + data.setPipeBreakAlarm(((DataItemNCX)dataItem).getDestroy()); + data.setGasAlarm(((DataItemNCX)dataItem).getLeak()); + data.setLeftOfflineAlarm(((DataItemNCX)dataItem).getDiscL()); + data.setRightOfflineAlarm(((DataItemNCX)dataItem).getDiscR()); + data.setLeftVibrateAlarm(((DataItemNCX)dataItem).getVibL()); + data.setRightVibrateAlarm(((DataItemNCX)dataItem).getVibR()); + data.setUptime(LocalDateTime.parse(((DataItemNCX)dataItem).getTime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 采集时间 + data.setLogtime(LocalDateTime.parse(getUptime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 上报时间 + + dataList.add(data); + } + + return dataList; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java new file mode 100644 index 0000000..372ac73 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java @@ -0,0 +1,31 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.DataItem; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class DataItemNCX extends DataItem { + String lenL; // 左侧指示带长度 + String lenR; // 右侧指示带长度 + String ch4L; // 左侧甲烷浓度值 + String ch4R; // 右侧甲烷浓度值 + String bat; // 电池电压 + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String spare; // 备用 + String time; // 采集时间 + + @Override + public String toString() { + return "气体浓度值:" + "(" + ch4L + "," + ch4R + ")" + "%LEL;" + + "电池电压值:" + bat + "v;" + + "采样时间:" + time; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java new file mode 100644 index 0000000..b3bbcf4 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java @@ -0,0 +1,43 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.EventFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class EventFrameNCX extends EventFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + eventItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + EventItemNCX eventItem = new EventItemNCX(); + + eventItem.setSlope(dataObj.getString("SLOPING")); + eventItem.setDestroy(dataObj.getString("DESTROY")); + eventItem.setLeak(dataObj.getString("LEAK")); + eventItem.setDiscL(dataObj.getString("DISCL")); + eventItem.setDiscR(dataObj.getString("DISCR")); + eventItem.setVibL(dataObj.getString("VIBL")); + eventItem.setVibR(dataObj.getString("VIBR")); + eventItem.setTime(dataObj.getString("UPTIME")); + + eventItemList.add(eventItem); + } + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java new file mode 100644 index 0000000..1a560d0 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java @@ -0,0 +1,49 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.EventItem; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.commons.lang3.StringUtils; + +@EqualsAndHashCode(callSuper = true) +@Data +public class EventItemNCX extends EventItem { + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String time; // 采集时间 + + @Override + public String toString() { + String str = ""; + if (StringUtils.isNotBlank(slope) && slope.equalsIgnoreCase("1")) { + str += "[倾斜报警]"; + } + if (StringUtils.isNotBlank(destroy) && destroy.equalsIgnoreCase("1")) { + str += "[破坏报警]"; + } + if (StringUtils.isNotBlank(leak) && leak.equalsIgnoreCase("1")) { + str += "[甲烷泄漏报警]"; + } + if (StringUtils.isNotBlank(discL) && discL.equalsIgnoreCase("1")) { + str += "[左侧断线报警]"; + } + if (StringUtils.isNotBlank(discR) && discR.equalsIgnoreCase("1")) { + str += "[右侧断线报警]"; + } + if (StringUtils.isNotBlank(vibL) && vibL.equalsIgnoreCase("1")) { + str += "[左侧振动报警]"; + } + if (StringUtils.isNotBlank(vibR) && vibR.equalsIgnoreCase("1")) { + str += "[右侧振动报警]"; + } + str += "采样时间:" + time; + + return str; + + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java new file mode 100644 index 0000000..343c4d6 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java @@ -0,0 +1,37 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class InfoFrameNCX extends CasicFrame { + + String workMode; + String model; + String hwVersion; + String softVersion; + String sensorType; + + @Override + public String toString() { + return "设备编号: " + getDeviceCode() + "; " + + "设备工作模式: " + workMode + " ; " + + "设备型号: " + model + " ; " + + "版本号: " + hwVersion + ", " + softVersion + "; " + + "传感器类型: " + sensorType + " ; " + + "上报时间: " + getUptime(); + } + + @Override + public void parseMessageBody() { + workMode = getMessageBody().getString("WORKMODE"); + model = getMessageBody().getString("MODEL"); + hwVersion = getMessageBody().getString("HWVERSION"); + softVersion = getMessageBody().getString("SOFTVERSION"); + sensorType = getMessageBody().getString("SENSORTYPE"); + } +} diff --git a/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java new file mode 100644 index 0000000..e76fc86 --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java @@ -0,0 +1,14 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; + +public interface ISentinelFrameService { + + CasicFrame dataParse(String frame); + + String replyMessage(String deviceCode, String sequence); + + String doBuildCommand(CasicFrame cmd); + + void afterAction(CasicFrame frame); +} diff --git a/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java new file mode 100644 index 0000000..803ff0e --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java @@ -0,0 +1,109 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; +import com.casic.common.CasicFrameBuildFactory; +import com.casic.common.CasicProtocol; +import com.casic.common.general.DataFrame; +import com.casic.common.general.EventFrame; +import com.casic.common.general.ReplyFrame; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.model.DeviceWellView; +import com.casic.dao.service.IDataSentinelOtherService; +import com.casic.dao.service.IDeviceWellViewService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + + +@Service +@Slf4j +public class SentinelFrameServiceImpl implements ISentinelFrameService { + + @Resource + private CasicProtocol protocol; + + @Resource + IDataSentinelOtherService sentinelDataService; + + @Resource + IDeviceWellViewService deviceService; + + public CasicFrame dataParse(String frame) { + // 1. 判断帧结构 + boolean frameValid = protocol.checkFrame(frame); + if (frameValid) { + // 2. 获取帧结构中的关键字段信息 + String deviceId = protocol.getDeviceId(frame); + String deviceType = protocol.getDeviceType(frame); + String messageType = protocol.getMessageType(frame); + String messageBody = protocol.getMessageBody(frame).toUpperCase(); + String uptime = protocol.getUptime(frame); + String sequence = protocol.getMessageSequence(frame); + + String manufacturerCode = protocol.getManufacturerCode(frame); + CasicFrame sentinelFrame = CasicFrameBuildFactory.buildCasicFrame(messageType, manufacturerCode, deviceType); + + if (sentinelFrame != null) { + sentinelFrame.setDeviceCode(deviceId); + sentinelFrame.setUptime(uptime); + sentinelFrame.setMessageType(messageType); + sentinelFrame.setSequence(sequence); + + // 心跳类的消息不解析MessageBody + if (!sentinelFrame.getMessageType().equals("00")) { + sentinelFrame.setMessageBody(protocol.parseMessageBody(messageBody)); + sentinelFrame.parseMessageBody(); + } + + log.info("收到设备消息:{}", sentinelFrame); + return sentinelFrame; + } + } else { + log.error("消息帧解析异常"); + } + + return null; + } + + @Override + public String replyMessage(String deviceCode, String sequence) { + CasicFrame reply = new ReplyFrame(); + reply.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + reply.setDeviceCode(deviceCode); + reply.setSequence(sequence); + reply.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + return protocol.buildReplyFrameStr(reply); + } + + @Override + public String doBuildCommand(CasicFrame cmd) { + return protocol.buildFrameStr(cmd); + } + + @Override + public void afterAction(CasicFrame frame) { + // 数据消息帧 进行存库操作 + if (frame instanceof DataFrame) { + String devCode = frame.getDeviceCode(); + DeviceWellView devWellView = deviceService.getDeviceWellViewByDevCode(devCode); + String wellCode = ""; + if (devWellView != null) { + wellCode = devWellView.getWellCode(); + } + List dataList = ((DataFrame) frame).toDataModelList(); + if (dataList != null) { + for (Serializable item : dataList) { + DataMonitorPipeOther data = (DataMonitorPipeOther) item; + data.setWellCode(wellCode); + sentinelDataService.save(data); + } + } + } + } +} diff --git a/src/main/java/com/casic/tube/controller/TubeDataController.java b/src/main/java/com/casic/tube/controller/TubeDataController.java index 61486c5..4965449 100644 --- a/src/main/java/com/casic/tube/controller/TubeDataController.java +++ b/src/main/java/com/casic/tube/controller/TubeDataController.java @@ -2,8 +2,8 @@ import com.alibaba.fastjson.JSONObject; import com.casic.common.CasicFrame; -import com.casic.tube.frame.ConfigFrame; -import com.casic.tube.service.ITubeDataService; +import com.casic.common.general.ConfigFrame; +import com.casic.tube.service.ITubeFrameService; import com.casic.util.aep.AepCommandSend; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestBody; @@ -21,7 +21,7 @@ public class TubeDataController { @Resource - private ITubeDataService tubeDataService; + private ITubeFrameService frameService; @RequestMapping("/tube/data/recv") public Object dataRecv(@RequestBody Map map) { @@ -42,10 +42,10 @@ String frameStr = new String(baseBytes); // 根据协议进行解析 - CasicFrame frame = tubeDataService.dataParse(frameStr); + CasicFrame frame = frameService.dataParse(frameStr); // 存库 - tubeDataService.afterAction(frame); + frameService.afterAction(frame); retObj.put("code", 200); retObj.put("success", true); @@ -74,7 +74,7 @@ messageBody.put("datas", map.get("cmdList")); cmdFrame.setMessageBody(messageBody); - String frameStr = tubeDataService.doBuildCommand(cmdFrame); + String frameStr = frameService.doBuildCommand(cmdFrame); // TODO-LIST // 这三个参数根据设备编号从数据库中取 diff --git a/src/main/java/com/casic/tube/frame/ConfigFrame.java b/src/main/java/com/casic/tube/frame/ConfigFrame.java deleted file mode 100644 index 883dad6..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigFrame.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigFrame extends CasicFrame { - - public ConfigFrame() { - setSequence("01"); // 默认序号 - setControl("1"); // 默认为不需要分包 - setMessageType("52"); // 消息大类 52 = SetRequest - } -} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java new file mode 100644 index 0000000..95d2bd4 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java @@ -0,0 +1,8 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.DataMonitorPipeOther; + +public interface IDataSentinelOtherService extends IService { + +} diff --git a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java index d6b1200..0290829 100644 --- a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java +++ b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java @@ -1,7 +1,6 @@ package com.casic.dao.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.dao.model.DataTubeOther; import com.casic.dao.model.DeviceWellView; public interface IDeviceWellViewService extends IService { diff --git a/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java new file mode 100644 index 0000000..be34f77 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java @@ -0,0 +1,16 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.BusDeviceMapper; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import org.springframework.stereotype.Service; + +@Service +public class BusDeviceServiceImpl extends ServiceImpl implements IBusDeviceService { + + @Override + public BusDevice getDeviceByCode(String devCode) { + return baseMapper.getOneByDevCode(devCode); + } +} diff --git a/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java new file mode 100644 index 0000000..0db2007 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java @@ -0,0 +1,11 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.DataSentinelOtherMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.service.IDataSentinelOtherService; +import org.springframework.stereotype.Service; + +@Service +public class DataSentinelOtherServiceImpl extends ServiceImpl implements IDataSentinelOtherService { +} diff --git a/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java new file mode 100644 index 0000000..d8c5ef2 --- /dev/null +++ b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java @@ -0,0 +1,111 @@ +package com.casic.protocol; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.CasicProtocol; +import org.springframework.stereotype.Component; + +@Component +public class CasicTubeProtocolImpl implements CasicProtocol { + @Override + public boolean checkFrame(String frame) { + boolean valid = checkFrameHeaderAndTail(frame); + if (valid) { + valid = checkFrameLength(frame); + } + + return valid; + } + + private boolean checkFrameHeaderAndTail(String frame) { + return (frame.substring(0, 2).equalsIgnoreCase("AA")) && + (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); + } + + private boolean checkFrameLength(String frame) { + String lengthStr = frame.substring(4, 7); + int length = Integer.parseInt(lengthStr); + + return frame.length() == length + 9; + } + + @Override + public String getDeviceType(String frame) { + return frame.substring(7, 9); + } + + @Override + public String getDeviceId(String frame) { + return frame.substring(9, 21); + } + + @Override + public String getManufacturerCode(String frame) { + return frame.substring(11, 13); + } + + @Override + public String getMessageType(String frame) { + return frame.substring(21, 23); + } + + @Override + public String getMessageSequence(String frame) { + return frame.substring(23, 25); + } + + @Override + public String getMessageBody(String frame) { + return frame.substring(26, frame.length() - 16); + } + + @Override + public JSONObject parseMessageBody(String messageBody) { + return JSONObject.parseObject(messageBody); + } + + @Override + public String getUptime(String frame) { + return frame.substring(frame.length() - 16, frame.length() - 2); + } + + @Override + public String buildFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append(frame.getMessageBody().toJSONString()); + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } + + @Override + public String buildReplyFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append("00"); // 消息响应类消息 消息体为00 + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/senitnel/controller/SentinelDataController.java b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java new file mode 100644 index 0000000..633c072 --- /dev/null +++ b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java @@ -0,0 +1,120 @@ +package com.casic.senitnel.controller; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.general.ConfigFrame; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import com.casic.senitnel.service.ISentinelFrameService; +import com.casic.util.aep.AepCommandSend; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Base64; +import java.util.Map; + +@Slf4j +@RestController +public class SentinelDataController { + + @Resource + private ISentinelFrameService frameService; + + @Resource + private IBusDeviceService deviceService; + + @RequestMapping("/sentinel/data/recv") + public Object dataRecv(@RequestBody Map map) { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + + JSONObject recvObj = (JSONObject) JSONObject.toJSON(map); + if (recvObj.containsKey("payload")) { + JSONObject payload = recvObj.getJSONObject("payload"); + String value = payload.getString("APPdata"); + + if (value.isEmpty()) { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } else { + byte[] baseBytes = Base64.getDecoder().decode(value); + String frameStr = new String(baseBytes); + + // 根据协议进行解析 + CasicFrame frame = frameService.dataParse(frameStr); + + if (frame != null) { + // 回复响应 + String replyFrameStr = frameService.replyMessage(frame.getDeviceCode(), frame.getSequence()); + + // 从数据库中获取master-api-key 回复响应消息 + BusDevice device = deviceService.getDeviceByCode(frame.getDeviceCode()); + if (device != null && StringUtils.isNotBlank(device.getMasterApiKey())) { + String masterApiKey = device.getMasterApiKey(); + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + + try { + int code = aepCommandSend.handleAndReply(replyFrameStr); + } catch (Exception ex) { + log.error("向设备回复响应异常:{}", ex.getMessage()); + } + } + + // 存库 + frameService.afterAction(frame); + } + + retObj.put("code", 200); + retObj.put("success", true); + } + } else { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } + + return retObj; + } + + @RequestMapping("/sentinel/config/send") + public Object configSend(@RequestBody Map map) throws Exception { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + CasicFrame cmdFrame = new ConfigFrame(); + cmdFrame.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + cmdFrame.setDeviceCode((String) map.get("devCode")); + cmdFrame.setSequence("01"); + cmdFrame.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + JSONObject messageBody = new JSONObject(); + messageBody.put("datas", map.get("cmdList")); + cmdFrame.setMessageBody(messageBody); + + String frameStr = frameService.doBuildCommand(cmdFrame); + + // TODO-LIST + // 这三个参数根据设备编号从数据库中取 + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + String masterApiKey = (String) map.get("masterApiKey"); + + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + int code = aepCommandSend.handleAndReply(frameStr); + + retObj.put("code", 200); + retObj.put("success", true); + retObj.put("AEPRetCode", code); + return retObj; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java new file mode 100644 index 0000000..368af03 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java @@ -0,0 +1,82 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; +import com.casic.dao.model.DataMonitorPipeOther; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class DataFrameNCX extends DataFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + dataItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + DataItemNCX dataItem = new DataItemNCX(); + + dataItem.setLenL(dataObj.getString("LENGL")); + dataItem.setLenR(dataObj.getString("LENGR")); + dataItem.setBat(dataObj.getString("BAT")); + dataItem.setCh4L(dataObj.getString("CH4L")); + dataItem.setCh4R(dataObj.getString("CH4R")); + dataItem.setSlope(dataObj.getString("SLOPING")); + dataItem.setDestroy(dataObj.getString("DESTROY")); + dataItem.setLeak(dataObj.getString("LEAK")); + dataItem.setDiscL(dataObj.getString("DISCL")); + dataItem.setDiscR(dataObj.getString("DISCR")); + dataItem.setVibL(dataObj.getString("VIBL")); + dataItem.setVibR(dataObj.getString("VIBR")); + dataItem.setTime(dataObj.getString("UPTIME")); + + dataItemList.add(dataItem); + } + } + + @Override + public List toDataModelList() { + List dataList = new ArrayList<>(); + for (DataItem dataItem : dataItemList) { + DataMonitorPipeOther data = new DataMonitorPipeOther(); + + data.setDevcode(getDeviceCode()); + data.setLeftLength(((DataItemNCX)dataItem).getLenL()); + data.setRightLength(((DataItemNCX)dataItem).getLenR()); + data.setLeftGas(((DataItemNCX)dataItem).getCh4L()); + data.setRightGas(((DataItemNCX)dataItem).getCh4R()); + data.setVbat(((DataItemNCX)dataItem).getBat()); + data.setPipeInclineAlarm(((DataItemNCX)dataItem).getSlope()); + data.setPipeBreakAlarm(((DataItemNCX)dataItem).getDestroy()); + data.setGasAlarm(((DataItemNCX)dataItem).getLeak()); + data.setLeftOfflineAlarm(((DataItemNCX)dataItem).getDiscL()); + data.setRightOfflineAlarm(((DataItemNCX)dataItem).getDiscR()); + data.setLeftVibrateAlarm(((DataItemNCX)dataItem).getVibL()); + data.setRightVibrateAlarm(((DataItemNCX)dataItem).getVibR()); + data.setUptime(LocalDateTime.parse(((DataItemNCX)dataItem).getTime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 采集时间 + data.setLogtime(LocalDateTime.parse(getUptime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 上报时间 + + dataList.add(data); + } + + return dataList; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java new file mode 100644 index 0000000..372ac73 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java @@ -0,0 +1,31 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.DataItem; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class DataItemNCX extends DataItem { + String lenL; // 左侧指示带长度 + String lenR; // 右侧指示带长度 + String ch4L; // 左侧甲烷浓度值 + String ch4R; // 右侧甲烷浓度值 + String bat; // 电池电压 + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String spare; // 备用 + String time; // 采集时间 + + @Override + public String toString() { + return "气体浓度值:" + "(" + ch4L + "," + ch4R + ")" + "%LEL;" + + "电池电压值:" + bat + "v;" + + "采样时间:" + time; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java new file mode 100644 index 0000000..b3bbcf4 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java @@ -0,0 +1,43 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.EventFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class EventFrameNCX extends EventFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + eventItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + EventItemNCX eventItem = new EventItemNCX(); + + eventItem.setSlope(dataObj.getString("SLOPING")); + eventItem.setDestroy(dataObj.getString("DESTROY")); + eventItem.setLeak(dataObj.getString("LEAK")); + eventItem.setDiscL(dataObj.getString("DISCL")); + eventItem.setDiscR(dataObj.getString("DISCR")); + eventItem.setVibL(dataObj.getString("VIBL")); + eventItem.setVibR(dataObj.getString("VIBR")); + eventItem.setTime(dataObj.getString("UPTIME")); + + eventItemList.add(eventItem); + } + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java new file mode 100644 index 0000000..1a560d0 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java @@ -0,0 +1,49 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.EventItem; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.commons.lang3.StringUtils; + +@EqualsAndHashCode(callSuper = true) +@Data +public class EventItemNCX extends EventItem { + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String time; // 采集时间 + + @Override + public String toString() { + String str = ""; + if (StringUtils.isNotBlank(slope) && slope.equalsIgnoreCase("1")) { + str += "[倾斜报警]"; + } + if (StringUtils.isNotBlank(destroy) && destroy.equalsIgnoreCase("1")) { + str += "[破坏报警]"; + } + if (StringUtils.isNotBlank(leak) && leak.equalsIgnoreCase("1")) { + str += "[甲烷泄漏报警]"; + } + if (StringUtils.isNotBlank(discL) && discL.equalsIgnoreCase("1")) { + str += "[左侧断线报警]"; + } + if (StringUtils.isNotBlank(discR) && discR.equalsIgnoreCase("1")) { + str += "[右侧断线报警]"; + } + if (StringUtils.isNotBlank(vibL) && vibL.equalsIgnoreCase("1")) { + str += "[左侧振动报警]"; + } + if (StringUtils.isNotBlank(vibR) && vibR.equalsIgnoreCase("1")) { + str += "[右侧振动报警]"; + } + str += "采样时间:" + time; + + return str; + + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java new file mode 100644 index 0000000..343c4d6 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java @@ -0,0 +1,37 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class InfoFrameNCX extends CasicFrame { + + String workMode; + String model; + String hwVersion; + String softVersion; + String sensorType; + + @Override + public String toString() { + return "设备编号: " + getDeviceCode() + "; " + + "设备工作模式: " + workMode + " ; " + + "设备型号: " + model + " ; " + + "版本号: " + hwVersion + ", " + softVersion + "; " + + "传感器类型: " + sensorType + " ; " + + "上报时间: " + getUptime(); + } + + @Override + public void parseMessageBody() { + workMode = getMessageBody().getString("WORKMODE"); + model = getMessageBody().getString("MODEL"); + hwVersion = getMessageBody().getString("HWVERSION"); + softVersion = getMessageBody().getString("SOFTVERSION"); + sensorType = getMessageBody().getString("SENSORTYPE"); + } +} diff --git a/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java new file mode 100644 index 0000000..e76fc86 --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java @@ -0,0 +1,14 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; + +public interface ISentinelFrameService { + + CasicFrame dataParse(String frame); + + String replyMessage(String deviceCode, String sequence); + + String doBuildCommand(CasicFrame cmd); + + void afterAction(CasicFrame frame); +} diff --git a/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java new file mode 100644 index 0000000..803ff0e --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java @@ -0,0 +1,109 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; +import com.casic.common.CasicFrameBuildFactory; +import com.casic.common.CasicProtocol; +import com.casic.common.general.DataFrame; +import com.casic.common.general.EventFrame; +import com.casic.common.general.ReplyFrame; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.model.DeviceWellView; +import com.casic.dao.service.IDataSentinelOtherService; +import com.casic.dao.service.IDeviceWellViewService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + + +@Service +@Slf4j +public class SentinelFrameServiceImpl implements ISentinelFrameService { + + @Resource + private CasicProtocol protocol; + + @Resource + IDataSentinelOtherService sentinelDataService; + + @Resource + IDeviceWellViewService deviceService; + + public CasicFrame dataParse(String frame) { + // 1. 判断帧结构 + boolean frameValid = protocol.checkFrame(frame); + if (frameValid) { + // 2. 获取帧结构中的关键字段信息 + String deviceId = protocol.getDeviceId(frame); + String deviceType = protocol.getDeviceType(frame); + String messageType = protocol.getMessageType(frame); + String messageBody = protocol.getMessageBody(frame).toUpperCase(); + String uptime = protocol.getUptime(frame); + String sequence = protocol.getMessageSequence(frame); + + String manufacturerCode = protocol.getManufacturerCode(frame); + CasicFrame sentinelFrame = CasicFrameBuildFactory.buildCasicFrame(messageType, manufacturerCode, deviceType); + + if (sentinelFrame != null) { + sentinelFrame.setDeviceCode(deviceId); + sentinelFrame.setUptime(uptime); + sentinelFrame.setMessageType(messageType); + sentinelFrame.setSequence(sequence); + + // 心跳类的消息不解析MessageBody + if (!sentinelFrame.getMessageType().equals("00")) { + sentinelFrame.setMessageBody(protocol.parseMessageBody(messageBody)); + sentinelFrame.parseMessageBody(); + } + + log.info("收到设备消息:{}", sentinelFrame); + return sentinelFrame; + } + } else { + log.error("消息帧解析异常"); + } + + return null; + } + + @Override + public String replyMessage(String deviceCode, String sequence) { + CasicFrame reply = new ReplyFrame(); + reply.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + reply.setDeviceCode(deviceCode); + reply.setSequence(sequence); + reply.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + return protocol.buildReplyFrameStr(reply); + } + + @Override + public String doBuildCommand(CasicFrame cmd) { + return protocol.buildFrameStr(cmd); + } + + @Override + public void afterAction(CasicFrame frame) { + // 数据消息帧 进行存库操作 + if (frame instanceof DataFrame) { + String devCode = frame.getDeviceCode(); + DeviceWellView devWellView = deviceService.getDeviceWellViewByDevCode(devCode); + String wellCode = ""; + if (devWellView != null) { + wellCode = devWellView.getWellCode(); + } + List dataList = ((DataFrame) frame).toDataModelList(); + if (dataList != null) { + for (Serializable item : dataList) { + DataMonitorPipeOther data = (DataMonitorPipeOther) item; + data.setWellCode(wellCode); + sentinelDataService.save(data); + } + } + } + } +} diff --git a/src/main/java/com/casic/tube/controller/TubeDataController.java b/src/main/java/com/casic/tube/controller/TubeDataController.java index 61486c5..4965449 100644 --- a/src/main/java/com/casic/tube/controller/TubeDataController.java +++ b/src/main/java/com/casic/tube/controller/TubeDataController.java @@ -2,8 +2,8 @@ import com.alibaba.fastjson.JSONObject; import com.casic.common.CasicFrame; -import com.casic.tube.frame.ConfigFrame; -import com.casic.tube.service.ITubeDataService; +import com.casic.common.general.ConfigFrame; +import com.casic.tube.service.ITubeFrameService; import com.casic.util.aep.AepCommandSend; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestBody; @@ -21,7 +21,7 @@ public class TubeDataController { @Resource - private ITubeDataService tubeDataService; + private ITubeFrameService frameService; @RequestMapping("/tube/data/recv") public Object dataRecv(@RequestBody Map map) { @@ -42,10 +42,10 @@ String frameStr = new String(baseBytes); // 根据协议进行解析 - CasicFrame frame = tubeDataService.dataParse(frameStr); + CasicFrame frame = frameService.dataParse(frameStr); // 存库 - tubeDataService.afterAction(frame); + frameService.afterAction(frame); retObj.put("code", 200); retObj.put("success", true); @@ -74,7 +74,7 @@ messageBody.put("datas", map.get("cmdList")); cmdFrame.setMessageBody(messageBody); - String frameStr = tubeDataService.doBuildCommand(cmdFrame); + String frameStr = frameService.doBuildCommand(cmdFrame); // TODO-LIST // 这三个参数根据设备编号从数据库中取 diff --git a/src/main/java/com/casic/tube/frame/ConfigFrame.java b/src/main/java/com/casic/tube/frame/ConfigFrame.java deleted file mode 100644 index 883dad6..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigFrame.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigFrame extends CasicFrame { - - public ConfigFrame() { - setSequence("01"); // 默认序号 - setControl("1"); // 默认为不需要分包 - setMessageType("52"); // 消息大类 52 = SetRequest - } -} diff --git a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java b/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java deleted file mode 100644 index a419145..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigResponseFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "03"; - final String MESSAGE_TYPE_STRING = "SetResponse"; - final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "指令序号" + getSequence() + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java new file mode 100644 index 0000000..95d2bd4 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java @@ -0,0 +1,8 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.DataMonitorPipeOther; + +public interface IDataSentinelOtherService extends IService { + +} diff --git a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java index d6b1200..0290829 100644 --- a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java +++ b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java @@ -1,7 +1,6 @@ package com.casic.dao.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.dao.model.DataTubeOther; import com.casic.dao.model.DeviceWellView; public interface IDeviceWellViewService extends IService { diff --git a/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java new file mode 100644 index 0000000..be34f77 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java @@ -0,0 +1,16 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.BusDeviceMapper; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import org.springframework.stereotype.Service; + +@Service +public class BusDeviceServiceImpl extends ServiceImpl implements IBusDeviceService { + + @Override + public BusDevice getDeviceByCode(String devCode) { + return baseMapper.getOneByDevCode(devCode); + } +} diff --git a/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java new file mode 100644 index 0000000..0db2007 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java @@ -0,0 +1,11 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.DataSentinelOtherMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.service.IDataSentinelOtherService; +import org.springframework.stereotype.Service; + +@Service +public class DataSentinelOtherServiceImpl extends ServiceImpl implements IDataSentinelOtherService { +} diff --git a/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java new file mode 100644 index 0000000..d8c5ef2 --- /dev/null +++ b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java @@ -0,0 +1,111 @@ +package com.casic.protocol; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.CasicProtocol; +import org.springframework.stereotype.Component; + +@Component +public class CasicTubeProtocolImpl implements CasicProtocol { + @Override + public boolean checkFrame(String frame) { + boolean valid = checkFrameHeaderAndTail(frame); + if (valid) { + valid = checkFrameLength(frame); + } + + return valid; + } + + private boolean checkFrameHeaderAndTail(String frame) { + return (frame.substring(0, 2).equalsIgnoreCase("AA")) && + (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); + } + + private boolean checkFrameLength(String frame) { + String lengthStr = frame.substring(4, 7); + int length = Integer.parseInt(lengthStr); + + return frame.length() == length + 9; + } + + @Override + public String getDeviceType(String frame) { + return frame.substring(7, 9); + } + + @Override + public String getDeviceId(String frame) { + return frame.substring(9, 21); + } + + @Override + public String getManufacturerCode(String frame) { + return frame.substring(11, 13); + } + + @Override + public String getMessageType(String frame) { + return frame.substring(21, 23); + } + + @Override + public String getMessageSequence(String frame) { + return frame.substring(23, 25); + } + + @Override + public String getMessageBody(String frame) { + return frame.substring(26, frame.length() - 16); + } + + @Override + public JSONObject parseMessageBody(String messageBody) { + return JSONObject.parseObject(messageBody); + } + + @Override + public String getUptime(String frame) { + return frame.substring(frame.length() - 16, frame.length() - 2); + } + + @Override + public String buildFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append(frame.getMessageBody().toJSONString()); + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } + + @Override + public String buildReplyFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append("00"); // 消息响应类消息 消息体为00 + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/senitnel/controller/SentinelDataController.java b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java new file mode 100644 index 0000000..633c072 --- /dev/null +++ b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java @@ -0,0 +1,120 @@ +package com.casic.senitnel.controller; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.general.ConfigFrame; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import com.casic.senitnel.service.ISentinelFrameService; +import com.casic.util.aep.AepCommandSend; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Base64; +import java.util.Map; + +@Slf4j +@RestController +public class SentinelDataController { + + @Resource + private ISentinelFrameService frameService; + + @Resource + private IBusDeviceService deviceService; + + @RequestMapping("/sentinel/data/recv") + public Object dataRecv(@RequestBody Map map) { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + + JSONObject recvObj = (JSONObject) JSONObject.toJSON(map); + if (recvObj.containsKey("payload")) { + JSONObject payload = recvObj.getJSONObject("payload"); + String value = payload.getString("APPdata"); + + if (value.isEmpty()) { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } else { + byte[] baseBytes = Base64.getDecoder().decode(value); + String frameStr = new String(baseBytes); + + // 根据协议进行解析 + CasicFrame frame = frameService.dataParse(frameStr); + + if (frame != null) { + // 回复响应 + String replyFrameStr = frameService.replyMessage(frame.getDeviceCode(), frame.getSequence()); + + // 从数据库中获取master-api-key 回复响应消息 + BusDevice device = deviceService.getDeviceByCode(frame.getDeviceCode()); + if (device != null && StringUtils.isNotBlank(device.getMasterApiKey())) { + String masterApiKey = device.getMasterApiKey(); + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + + try { + int code = aepCommandSend.handleAndReply(replyFrameStr); + } catch (Exception ex) { + log.error("向设备回复响应异常:{}", ex.getMessage()); + } + } + + // 存库 + frameService.afterAction(frame); + } + + retObj.put("code", 200); + retObj.put("success", true); + } + } else { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } + + return retObj; + } + + @RequestMapping("/sentinel/config/send") + public Object configSend(@RequestBody Map map) throws Exception { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + CasicFrame cmdFrame = new ConfigFrame(); + cmdFrame.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + cmdFrame.setDeviceCode((String) map.get("devCode")); + cmdFrame.setSequence("01"); + cmdFrame.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + JSONObject messageBody = new JSONObject(); + messageBody.put("datas", map.get("cmdList")); + cmdFrame.setMessageBody(messageBody); + + String frameStr = frameService.doBuildCommand(cmdFrame); + + // TODO-LIST + // 这三个参数根据设备编号从数据库中取 + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + String masterApiKey = (String) map.get("masterApiKey"); + + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + int code = aepCommandSend.handleAndReply(frameStr); + + retObj.put("code", 200); + retObj.put("success", true); + retObj.put("AEPRetCode", code); + return retObj; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java new file mode 100644 index 0000000..368af03 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java @@ -0,0 +1,82 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; +import com.casic.dao.model.DataMonitorPipeOther; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class DataFrameNCX extends DataFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + dataItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + DataItemNCX dataItem = new DataItemNCX(); + + dataItem.setLenL(dataObj.getString("LENGL")); + dataItem.setLenR(dataObj.getString("LENGR")); + dataItem.setBat(dataObj.getString("BAT")); + dataItem.setCh4L(dataObj.getString("CH4L")); + dataItem.setCh4R(dataObj.getString("CH4R")); + dataItem.setSlope(dataObj.getString("SLOPING")); + dataItem.setDestroy(dataObj.getString("DESTROY")); + dataItem.setLeak(dataObj.getString("LEAK")); + dataItem.setDiscL(dataObj.getString("DISCL")); + dataItem.setDiscR(dataObj.getString("DISCR")); + dataItem.setVibL(dataObj.getString("VIBL")); + dataItem.setVibR(dataObj.getString("VIBR")); + dataItem.setTime(dataObj.getString("UPTIME")); + + dataItemList.add(dataItem); + } + } + + @Override + public List toDataModelList() { + List dataList = new ArrayList<>(); + for (DataItem dataItem : dataItemList) { + DataMonitorPipeOther data = new DataMonitorPipeOther(); + + data.setDevcode(getDeviceCode()); + data.setLeftLength(((DataItemNCX)dataItem).getLenL()); + data.setRightLength(((DataItemNCX)dataItem).getLenR()); + data.setLeftGas(((DataItemNCX)dataItem).getCh4L()); + data.setRightGas(((DataItemNCX)dataItem).getCh4R()); + data.setVbat(((DataItemNCX)dataItem).getBat()); + data.setPipeInclineAlarm(((DataItemNCX)dataItem).getSlope()); + data.setPipeBreakAlarm(((DataItemNCX)dataItem).getDestroy()); + data.setGasAlarm(((DataItemNCX)dataItem).getLeak()); + data.setLeftOfflineAlarm(((DataItemNCX)dataItem).getDiscL()); + data.setRightOfflineAlarm(((DataItemNCX)dataItem).getDiscR()); + data.setLeftVibrateAlarm(((DataItemNCX)dataItem).getVibL()); + data.setRightVibrateAlarm(((DataItemNCX)dataItem).getVibR()); + data.setUptime(LocalDateTime.parse(((DataItemNCX)dataItem).getTime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 采集时间 + data.setLogtime(LocalDateTime.parse(getUptime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 上报时间 + + dataList.add(data); + } + + return dataList; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java new file mode 100644 index 0000000..372ac73 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java @@ -0,0 +1,31 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.DataItem; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class DataItemNCX extends DataItem { + String lenL; // 左侧指示带长度 + String lenR; // 右侧指示带长度 + String ch4L; // 左侧甲烷浓度值 + String ch4R; // 右侧甲烷浓度值 + String bat; // 电池电压 + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String spare; // 备用 + String time; // 采集时间 + + @Override + public String toString() { + return "气体浓度值:" + "(" + ch4L + "," + ch4R + ")" + "%LEL;" + + "电池电压值:" + bat + "v;" + + "采样时间:" + time; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java new file mode 100644 index 0000000..b3bbcf4 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java @@ -0,0 +1,43 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.EventFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class EventFrameNCX extends EventFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + eventItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + EventItemNCX eventItem = new EventItemNCX(); + + eventItem.setSlope(dataObj.getString("SLOPING")); + eventItem.setDestroy(dataObj.getString("DESTROY")); + eventItem.setLeak(dataObj.getString("LEAK")); + eventItem.setDiscL(dataObj.getString("DISCL")); + eventItem.setDiscR(dataObj.getString("DISCR")); + eventItem.setVibL(dataObj.getString("VIBL")); + eventItem.setVibR(dataObj.getString("VIBR")); + eventItem.setTime(dataObj.getString("UPTIME")); + + eventItemList.add(eventItem); + } + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java new file mode 100644 index 0000000..1a560d0 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java @@ -0,0 +1,49 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.EventItem; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.commons.lang3.StringUtils; + +@EqualsAndHashCode(callSuper = true) +@Data +public class EventItemNCX extends EventItem { + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String time; // 采集时间 + + @Override + public String toString() { + String str = ""; + if (StringUtils.isNotBlank(slope) && slope.equalsIgnoreCase("1")) { + str += "[倾斜报警]"; + } + if (StringUtils.isNotBlank(destroy) && destroy.equalsIgnoreCase("1")) { + str += "[破坏报警]"; + } + if (StringUtils.isNotBlank(leak) && leak.equalsIgnoreCase("1")) { + str += "[甲烷泄漏报警]"; + } + if (StringUtils.isNotBlank(discL) && discL.equalsIgnoreCase("1")) { + str += "[左侧断线报警]"; + } + if (StringUtils.isNotBlank(discR) && discR.equalsIgnoreCase("1")) { + str += "[右侧断线报警]"; + } + if (StringUtils.isNotBlank(vibL) && vibL.equalsIgnoreCase("1")) { + str += "[左侧振动报警]"; + } + if (StringUtils.isNotBlank(vibR) && vibR.equalsIgnoreCase("1")) { + str += "[右侧振动报警]"; + } + str += "采样时间:" + time; + + return str; + + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java new file mode 100644 index 0000000..343c4d6 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java @@ -0,0 +1,37 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class InfoFrameNCX extends CasicFrame { + + String workMode; + String model; + String hwVersion; + String softVersion; + String sensorType; + + @Override + public String toString() { + return "设备编号: " + getDeviceCode() + "; " + + "设备工作模式: " + workMode + " ; " + + "设备型号: " + model + " ; " + + "版本号: " + hwVersion + ", " + softVersion + "; " + + "传感器类型: " + sensorType + " ; " + + "上报时间: " + getUptime(); + } + + @Override + public void parseMessageBody() { + workMode = getMessageBody().getString("WORKMODE"); + model = getMessageBody().getString("MODEL"); + hwVersion = getMessageBody().getString("HWVERSION"); + softVersion = getMessageBody().getString("SOFTVERSION"); + sensorType = getMessageBody().getString("SENSORTYPE"); + } +} diff --git a/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java new file mode 100644 index 0000000..e76fc86 --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java @@ -0,0 +1,14 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; + +public interface ISentinelFrameService { + + CasicFrame dataParse(String frame); + + String replyMessage(String deviceCode, String sequence); + + String doBuildCommand(CasicFrame cmd); + + void afterAction(CasicFrame frame); +} diff --git a/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java new file mode 100644 index 0000000..803ff0e --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java @@ -0,0 +1,109 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; +import com.casic.common.CasicFrameBuildFactory; +import com.casic.common.CasicProtocol; +import com.casic.common.general.DataFrame; +import com.casic.common.general.EventFrame; +import com.casic.common.general.ReplyFrame; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.model.DeviceWellView; +import com.casic.dao.service.IDataSentinelOtherService; +import com.casic.dao.service.IDeviceWellViewService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + + +@Service +@Slf4j +public class SentinelFrameServiceImpl implements ISentinelFrameService { + + @Resource + private CasicProtocol protocol; + + @Resource + IDataSentinelOtherService sentinelDataService; + + @Resource + IDeviceWellViewService deviceService; + + public CasicFrame dataParse(String frame) { + // 1. 判断帧结构 + boolean frameValid = protocol.checkFrame(frame); + if (frameValid) { + // 2. 获取帧结构中的关键字段信息 + String deviceId = protocol.getDeviceId(frame); + String deviceType = protocol.getDeviceType(frame); + String messageType = protocol.getMessageType(frame); + String messageBody = protocol.getMessageBody(frame).toUpperCase(); + String uptime = protocol.getUptime(frame); + String sequence = protocol.getMessageSequence(frame); + + String manufacturerCode = protocol.getManufacturerCode(frame); + CasicFrame sentinelFrame = CasicFrameBuildFactory.buildCasicFrame(messageType, manufacturerCode, deviceType); + + if (sentinelFrame != null) { + sentinelFrame.setDeviceCode(deviceId); + sentinelFrame.setUptime(uptime); + sentinelFrame.setMessageType(messageType); + sentinelFrame.setSequence(sequence); + + // 心跳类的消息不解析MessageBody + if (!sentinelFrame.getMessageType().equals("00")) { + sentinelFrame.setMessageBody(protocol.parseMessageBody(messageBody)); + sentinelFrame.parseMessageBody(); + } + + log.info("收到设备消息:{}", sentinelFrame); + return sentinelFrame; + } + } else { + log.error("消息帧解析异常"); + } + + return null; + } + + @Override + public String replyMessage(String deviceCode, String sequence) { + CasicFrame reply = new ReplyFrame(); + reply.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + reply.setDeviceCode(deviceCode); + reply.setSequence(sequence); + reply.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + return protocol.buildReplyFrameStr(reply); + } + + @Override + public String doBuildCommand(CasicFrame cmd) { + return protocol.buildFrameStr(cmd); + } + + @Override + public void afterAction(CasicFrame frame) { + // 数据消息帧 进行存库操作 + if (frame instanceof DataFrame) { + String devCode = frame.getDeviceCode(); + DeviceWellView devWellView = deviceService.getDeviceWellViewByDevCode(devCode); + String wellCode = ""; + if (devWellView != null) { + wellCode = devWellView.getWellCode(); + } + List dataList = ((DataFrame) frame).toDataModelList(); + if (dataList != null) { + for (Serializable item : dataList) { + DataMonitorPipeOther data = (DataMonitorPipeOther) item; + data.setWellCode(wellCode); + sentinelDataService.save(data); + } + } + } + } +} diff --git a/src/main/java/com/casic/tube/controller/TubeDataController.java b/src/main/java/com/casic/tube/controller/TubeDataController.java index 61486c5..4965449 100644 --- a/src/main/java/com/casic/tube/controller/TubeDataController.java +++ b/src/main/java/com/casic/tube/controller/TubeDataController.java @@ -2,8 +2,8 @@ import com.alibaba.fastjson.JSONObject; import com.casic.common.CasicFrame; -import com.casic.tube.frame.ConfigFrame; -import com.casic.tube.service.ITubeDataService; +import com.casic.common.general.ConfigFrame; +import com.casic.tube.service.ITubeFrameService; import com.casic.util.aep.AepCommandSend; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestBody; @@ -21,7 +21,7 @@ public class TubeDataController { @Resource - private ITubeDataService tubeDataService; + private ITubeFrameService frameService; @RequestMapping("/tube/data/recv") public Object dataRecv(@RequestBody Map map) { @@ -42,10 +42,10 @@ String frameStr = new String(baseBytes); // 根据协议进行解析 - CasicFrame frame = tubeDataService.dataParse(frameStr); + CasicFrame frame = frameService.dataParse(frameStr); // 存库 - tubeDataService.afterAction(frame); + frameService.afterAction(frame); retObj.put("code", 200); retObj.put("success", true); @@ -74,7 +74,7 @@ messageBody.put("datas", map.get("cmdList")); cmdFrame.setMessageBody(messageBody); - String frameStr = tubeDataService.doBuildCommand(cmdFrame); + String frameStr = frameService.doBuildCommand(cmdFrame); // TODO-LIST // 这三个参数根据设备编号从数据库中取 diff --git a/src/main/java/com/casic/tube/frame/ConfigFrame.java b/src/main/java/com/casic/tube/frame/ConfigFrame.java deleted file mode 100644 index 883dad6..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigFrame.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigFrame extends CasicFrame { - - public ConfigFrame() { - setSequence("01"); // 默认序号 - setControl("1"); // 默认为不需要分包 - setMessageType("52"); // 消息大类 52 = SetRequest - } -} diff --git a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java b/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java deleted file mode 100644 index a419145..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigResponseFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "03"; - final String MESSAGE_TYPE_STRING = "SetResponse"; - final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "指令序号" + getSequence() + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/DataFrame.java b/src/main/java/com/casic/tube/frame/DataFrame.java deleted file mode 100644 index 97e07b8..0000000 --- a/src/main/java/com/casic/tube/frame/DataFrame.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import com.casic.dao.model.DataTubeOther; - -import java.util.List; - -public class DataFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "02"; - final String MESSAGE_TYPE_STRING = "Data/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "数据消息/管盯"; - - public List dataItemList; - - public List toDataModelList() { - return null; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append(";"); - builder.append("上报时间:").append(getUptime()).append(";"); - for (DataItem dataItem : dataItemList) { - builder.append("["); - builder.append(dataItem); - builder.append("],"); - } - builder.deleteCharAt(builder.length() - 1); - builder.append("}"); - return builder.toString(); - } -} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java new file mode 100644 index 0000000..95d2bd4 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java @@ -0,0 +1,8 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.DataMonitorPipeOther; + +public interface IDataSentinelOtherService extends IService { + +} diff --git a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java index d6b1200..0290829 100644 --- a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java +++ b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java @@ -1,7 +1,6 @@ package com.casic.dao.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.dao.model.DataTubeOther; import com.casic.dao.model.DeviceWellView; public interface IDeviceWellViewService extends IService { diff --git a/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java new file mode 100644 index 0000000..be34f77 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java @@ -0,0 +1,16 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.BusDeviceMapper; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import org.springframework.stereotype.Service; + +@Service +public class BusDeviceServiceImpl extends ServiceImpl implements IBusDeviceService { + + @Override + public BusDevice getDeviceByCode(String devCode) { + return baseMapper.getOneByDevCode(devCode); + } +} diff --git a/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java new file mode 100644 index 0000000..0db2007 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java @@ -0,0 +1,11 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.DataSentinelOtherMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.service.IDataSentinelOtherService; +import org.springframework.stereotype.Service; + +@Service +public class DataSentinelOtherServiceImpl extends ServiceImpl implements IDataSentinelOtherService { +} diff --git a/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java new file mode 100644 index 0000000..d8c5ef2 --- /dev/null +++ b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java @@ -0,0 +1,111 @@ +package com.casic.protocol; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.CasicProtocol; +import org.springframework.stereotype.Component; + +@Component +public class CasicTubeProtocolImpl implements CasicProtocol { + @Override + public boolean checkFrame(String frame) { + boolean valid = checkFrameHeaderAndTail(frame); + if (valid) { + valid = checkFrameLength(frame); + } + + return valid; + } + + private boolean checkFrameHeaderAndTail(String frame) { + return (frame.substring(0, 2).equalsIgnoreCase("AA")) && + (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); + } + + private boolean checkFrameLength(String frame) { + String lengthStr = frame.substring(4, 7); + int length = Integer.parseInt(lengthStr); + + return frame.length() == length + 9; + } + + @Override + public String getDeviceType(String frame) { + return frame.substring(7, 9); + } + + @Override + public String getDeviceId(String frame) { + return frame.substring(9, 21); + } + + @Override + public String getManufacturerCode(String frame) { + return frame.substring(11, 13); + } + + @Override + public String getMessageType(String frame) { + return frame.substring(21, 23); + } + + @Override + public String getMessageSequence(String frame) { + return frame.substring(23, 25); + } + + @Override + public String getMessageBody(String frame) { + return frame.substring(26, frame.length() - 16); + } + + @Override + public JSONObject parseMessageBody(String messageBody) { + return JSONObject.parseObject(messageBody); + } + + @Override + public String getUptime(String frame) { + return frame.substring(frame.length() - 16, frame.length() - 2); + } + + @Override + public String buildFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append(frame.getMessageBody().toJSONString()); + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } + + @Override + public String buildReplyFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append("00"); // 消息响应类消息 消息体为00 + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/senitnel/controller/SentinelDataController.java b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java new file mode 100644 index 0000000..633c072 --- /dev/null +++ b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java @@ -0,0 +1,120 @@ +package com.casic.senitnel.controller; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.general.ConfigFrame; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import com.casic.senitnel.service.ISentinelFrameService; +import com.casic.util.aep.AepCommandSend; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Base64; +import java.util.Map; + +@Slf4j +@RestController +public class SentinelDataController { + + @Resource + private ISentinelFrameService frameService; + + @Resource + private IBusDeviceService deviceService; + + @RequestMapping("/sentinel/data/recv") + public Object dataRecv(@RequestBody Map map) { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + + JSONObject recvObj = (JSONObject) JSONObject.toJSON(map); + if (recvObj.containsKey("payload")) { + JSONObject payload = recvObj.getJSONObject("payload"); + String value = payload.getString("APPdata"); + + if (value.isEmpty()) { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } else { + byte[] baseBytes = Base64.getDecoder().decode(value); + String frameStr = new String(baseBytes); + + // 根据协议进行解析 + CasicFrame frame = frameService.dataParse(frameStr); + + if (frame != null) { + // 回复响应 + String replyFrameStr = frameService.replyMessage(frame.getDeviceCode(), frame.getSequence()); + + // 从数据库中获取master-api-key 回复响应消息 + BusDevice device = deviceService.getDeviceByCode(frame.getDeviceCode()); + if (device != null && StringUtils.isNotBlank(device.getMasterApiKey())) { + String masterApiKey = device.getMasterApiKey(); + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + + try { + int code = aepCommandSend.handleAndReply(replyFrameStr); + } catch (Exception ex) { + log.error("向设备回复响应异常:{}", ex.getMessage()); + } + } + + // 存库 + frameService.afterAction(frame); + } + + retObj.put("code", 200); + retObj.put("success", true); + } + } else { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } + + return retObj; + } + + @RequestMapping("/sentinel/config/send") + public Object configSend(@RequestBody Map map) throws Exception { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + CasicFrame cmdFrame = new ConfigFrame(); + cmdFrame.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + cmdFrame.setDeviceCode((String) map.get("devCode")); + cmdFrame.setSequence("01"); + cmdFrame.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + JSONObject messageBody = new JSONObject(); + messageBody.put("datas", map.get("cmdList")); + cmdFrame.setMessageBody(messageBody); + + String frameStr = frameService.doBuildCommand(cmdFrame); + + // TODO-LIST + // 这三个参数根据设备编号从数据库中取 + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + String masterApiKey = (String) map.get("masterApiKey"); + + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + int code = aepCommandSend.handleAndReply(frameStr); + + retObj.put("code", 200); + retObj.put("success", true); + retObj.put("AEPRetCode", code); + return retObj; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java new file mode 100644 index 0000000..368af03 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java @@ -0,0 +1,82 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; +import com.casic.dao.model.DataMonitorPipeOther; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class DataFrameNCX extends DataFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + dataItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + DataItemNCX dataItem = new DataItemNCX(); + + dataItem.setLenL(dataObj.getString("LENGL")); + dataItem.setLenR(dataObj.getString("LENGR")); + dataItem.setBat(dataObj.getString("BAT")); + dataItem.setCh4L(dataObj.getString("CH4L")); + dataItem.setCh4R(dataObj.getString("CH4R")); + dataItem.setSlope(dataObj.getString("SLOPING")); + dataItem.setDestroy(dataObj.getString("DESTROY")); + dataItem.setLeak(dataObj.getString("LEAK")); + dataItem.setDiscL(dataObj.getString("DISCL")); + dataItem.setDiscR(dataObj.getString("DISCR")); + dataItem.setVibL(dataObj.getString("VIBL")); + dataItem.setVibR(dataObj.getString("VIBR")); + dataItem.setTime(dataObj.getString("UPTIME")); + + dataItemList.add(dataItem); + } + } + + @Override + public List toDataModelList() { + List dataList = new ArrayList<>(); + for (DataItem dataItem : dataItemList) { + DataMonitorPipeOther data = new DataMonitorPipeOther(); + + data.setDevcode(getDeviceCode()); + data.setLeftLength(((DataItemNCX)dataItem).getLenL()); + data.setRightLength(((DataItemNCX)dataItem).getLenR()); + data.setLeftGas(((DataItemNCX)dataItem).getCh4L()); + data.setRightGas(((DataItemNCX)dataItem).getCh4R()); + data.setVbat(((DataItemNCX)dataItem).getBat()); + data.setPipeInclineAlarm(((DataItemNCX)dataItem).getSlope()); + data.setPipeBreakAlarm(((DataItemNCX)dataItem).getDestroy()); + data.setGasAlarm(((DataItemNCX)dataItem).getLeak()); + data.setLeftOfflineAlarm(((DataItemNCX)dataItem).getDiscL()); + data.setRightOfflineAlarm(((DataItemNCX)dataItem).getDiscR()); + data.setLeftVibrateAlarm(((DataItemNCX)dataItem).getVibL()); + data.setRightVibrateAlarm(((DataItemNCX)dataItem).getVibR()); + data.setUptime(LocalDateTime.parse(((DataItemNCX)dataItem).getTime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 采集时间 + data.setLogtime(LocalDateTime.parse(getUptime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 上报时间 + + dataList.add(data); + } + + return dataList; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java new file mode 100644 index 0000000..372ac73 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java @@ -0,0 +1,31 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.DataItem; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class DataItemNCX extends DataItem { + String lenL; // 左侧指示带长度 + String lenR; // 右侧指示带长度 + String ch4L; // 左侧甲烷浓度值 + String ch4R; // 右侧甲烷浓度值 + String bat; // 电池电压 + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String spare; // 备用 + String time; // 采集时间 + + @Override + public String toString() { + return "气体浓度值:" + "(" + ch4L + "," + ch4R + ")" + "%LEL;" + + "电池电压值:" + bat + "v;" + + "采样时间:" + time; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java new file mode 100644 index 0000000..b3bbcf4 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java @@ -0,0 +1,43 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.EventFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class EventFrameNCX extends EventFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + eventItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + EventItemNCX eventItem = new EventItemNCX(); + + eventItem.setSlope(dataObj.getString("SLOPING")); + eventItem.setDestroy(dataObj.getString("DESTROY")); + eventItem.setLeak(dataObj.getString("LEAK")); + eventItem.setDiscL(dataObj.getString("DISCL")); + eventItem.setDiscR(dataObj.getString("DISCR")); + eventItem.setVibL(dataObj.getString("VIBL")); + eventItem.setVibR(dataObj.getString("VIBR")); + eventItem.setTime(dataObj.getString("UPTIME")); + + eventItemList.add(eventItem); + } + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java new file mode 100644 index 0000000..1a560d0 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java @@ -0,0 +1,49 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.EventItem; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.commons.lang3.StringUtils; + +@EqualsAndHashCode(callSuper = true) +@Data +public class EventItemNCX extends EventItem { + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String time; // 采集时间 + + @Override + public String toString() { + String str = ""; + if (StringUtils.isNotBlank(slope) && slope.equalsIgnoreCase("1")) { + str += "[倾斜报警]"; + } + if (StringUtils.isNotBlank(destroy) && destroy.equalsIgnoreCase("1")) { + str += "[破坏报警]"; + } + if (StringUtils.isNotBlank(leak) && leak.equalsIgnoreCase("1")) { + str += "[甲烷泄漏报警]"; + } + if (StringUtils.isNotBlank(discL) && discL.equalsIgnoreCase("1")) { + str += "[左侧断线报警]"; + } + if (StringUtils.isNotBlank(discR) && discR.equalsIgnoreCase("1")) { + str += "[右侧断线报警]"; + } + if (StringUtils.isNotBlank(vibL) && vibL.equalsIgnoreCase("1")) { + str += "[左侧振动报警]"; + } + if (StringUtils.isNotBlank(vibR) && vibR.equalsIgnoreCase("1")) { + str += "[右侧振动报警]"; + } + str += "采样时间:" + time; + + return str; + + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java new file mode 100644 index 0000000..343c4d6 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java @@ -0,0 +1,37 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class InfoFrameNCX extends CasicFrame { + + String workMode; + String model; + String hwVersion; + String softVersion; + String sensorType; + + @Override + public String toString() { + return "设备编号: " + getDeviceCode() + "; " + + "设备工作模式: " + workMode + " ; " + + "设备型号: " + model + " ; " + + "版本号: " + hwVersion + ", " + softVersion + "; " + + "传感器类型: " + sensorType + " ; " + + "上报时间: " + getUptime(); + } + + @Override + public void parseMessageBody() { + workMode = getMessageBody().getString("WORKMODE"); + model = getMessageBody().getString("MODEL"); + hwVersion = getMessageBody().getString("HWVERSION"); + softVersion = getMessageBody().getString("SOFTVERSION"); + sensorType = getMessageBody().getString("SENSORTYPE"); + } +} diff --git a/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java new file mode 100644 index 0000000..e76fc86 --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java @@ -0,0 +1,14 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; + +public interface ISentinelFrameService { + + CasicFrame dataParse(String frame); + + String replyMessage(String deviceCode, String sequence); + + String doBuildCommand(CasicFrame cmd); + + void afterAction(CasicFrame frame); +} diff --git a/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java new file mode 100644 index 0000000..803ff0e --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java @@ -0,0 +1,109 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; +import com.casic.common.CasicFrameBuildFactory; +import com.casic.common.CasicProtocol; +import com.casic.common.general.DataFrame; +import com.casic.common.general.EventFrame; +import com.casic.common.general.ReplyFrame; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.model.DeviceWellView; +import com.casic.dao.service.IDataSentinelOtherService; +import com.casic.dao.service.IDeviceWellViewService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + + +@Service +@Slf4j +public class SentinelFrameServiceImpl implements ISentinelFrameService { + + @Resource + private CasicProtocol protocol; + + @Resource + IDataSentinelOtherService sentinelDataService; + + @Resource + IDeviceWellViewService deviceService; + + public CasicFrame dataParse(String frame) { + // 1. 判断帧结构 + boolean frameValid = protocol.checkFrame(frame); + if (frameValid) { + // 2. 获取帧结构中的关键字段信息 + String deviceId = protocol.getDeviceId(frame); + String deviceType = protocol.getDeviceType(frame); + String messageType = protocol.getMessageType(frame); + String messageBody = protocol.getMessageBody(frame).toUpperCase(); + String uptime = protocol.getUptime(frame); + String sequence = protocol.getMessageSequence(frame); + + String manufacturerCode = protocol.getManufacturerCode(frame); + CasicFrame sentinelFrame = CasicFrameBuildFactory.buildCasicFrame(messageType, manufacturerCode, deviceType); + + if (sentinelFrame != null) { + sentinelFrame.setDeviceCode(deviceId); + sentinelFrame.setUptime(uptime); + sentinelFrame.setMessageType(messageType); + sentinelFrame.setSequence(sequence); + + // 心跳类的消息不解析MessageBody + if (!sentinelFrame.getMessageType().equals("00")) { + sentinelFrame.setMessageBody(protocol.parseMessageBody(messageBody)); + sentinelFrame.parseMessageBody(); + } + + log.info("收到设备消息:{}", sentinelFrame); + return sentinelFrame; + } + } else { + log.error("消息帧解析异常"); + } + + return null; + } + + @Override + public String replyMessage(String deviceCode, String sequence) { + CasicFrame reply = new ReplyFrame(); + reply.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + reply.setDeviceCode(deviceCode); + reply.setSequence(sequence); + reply.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + return protocol.buildReplyFrameStr(reply); + } + + @Override + public String doBuildCommand(CasicFrame cmd) { + return protocol.buildFrameStr(cmd); + } + + @Override + public void afterAction(CasicFrame frame) { + // 数据消息帧 进行存库操作 + if (frame instanceof DataFrame) { + String devCode = frame.getDeviceCode(); + DeviceWellView devWellView = deviceService.getDeviceWellViewByDevCode(devCode); + String wellCode = ""; + if (devWellView != null) { + wellCode = devWellView.getWellCode(); + } + List dataList = ((DataFrame) frame).toDataModelList(); + if (dataList != null) { + for (Serializable item : dataList) { + DataMonitorPipeOther data = (DataMonitorPipeOther) item; + data.setWellCode(wellCode); + sentinelDataService.save(data); + } + } + } + } +} diff --git a/src/main/java/com/casic/tube/controller/TubeDataController.java b/src/main/java/com/casic/tube/controller/TubeDataController.java index 61486c5..4965449 100644 --- a/src/main/java/com/casic/tube/controller/TubeDataController.java +++ b/src/main/java/com/casic/tube/controller/TubeDataController.java @@ -2,8 +2,8 @@ import com.alibaba.fastjson.JSONObject; import com.casic.common.CasicFrame; -import com.casic.tube.frame.ConfigFrame; -import com.casic.tube.service.ITubeDataService; +import com.casic.common.general.ConfigFrame; +import com.casic.tube.service.ITubeFrameService; import com.casic.util.aep.AepCommandSend; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestBody; @@ -21,7 +21,7 @@ public class TubeDataController { @Resource - private ITubeDataService tubeDataService; + private ITubeFrameService frameService; @RequestMapping("/tube/data/recv") public Object dataRecv(@RequestBody Map map) { @@ -42,10 +42,10 @@ String frameStr = new String(baseBytes); // 根据协议进行解析 - CasicFrame frame = tubeDataService.dataParse(frameStr); + CasicFrame frame = frameService.dataParse(frameStr); // 存库 - tubeDataService.afterAction(frame); + frameService.afterAction(frame); retObj.put("code", 200); retObj.put("success", true); @@ -74,7 +74,7 @@ messageBody.put("datas", map.get("cmdList")); cmdFrame.setMessageBody(messageBody); - String frameStr = tubeDataService.doBuildCommand(cmdFrame); + String frameStr = frameService.doBuildCommand(cmdFrame); // TODO-LIST // 这三个参数根据设备编号从数据库中取 diff --git a/src/main/java/com/casic/tube/frame/ConfigFrame.java b/src/main/java/com/casic/tube/frame/ConfigFrame.java deleted file mode 100644 index 883dad6..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigFrame.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigFrame extends CasicFrame { - - public ConfigFrame() { - setSequence("01"); // 默认序号 - setControl("1"); // 默认为不需要分包 - setMessageType("52"); // 消息大类 52 = SetRequest - } -} diff --git a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java b/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java deleted file mode 100644 index a419145..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigResponseFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "03"; - final String MESSAGE_TYPE_STRING = "SetResponse"; - final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "指令序号" + getSequence() + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/DataFrame.java b/src/main/java/com/casic/tube/frame/DataFrame.java deleted file mode 100644 index 97e07b8..0000000 --- a/src/main/java/com/casic/tube/frame/DataFrame.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import com.casic.dao.model.DataTubeOther; - -import java.util.List; - -public class DataFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "02"; - final String MESSAGE_TYPE_STRING = "Data/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "数据消息/管盯"; - - public List dataItemList; - - public List toDataModelList() { - return null; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append(";"); - builder.append("上报时间:").append(getUptime()).append(";"); - for (DataItem dataItem : dataItemList) { - builder.append("["); - builder.append(dataItem); - builder.append("],"); - } - builder.deleteCharAt(builder.length() - 1); - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/DataItem.java b/src/main/java/com/casic/tube/frame/DataItem.java deleted file mode 100644 index 4e9aceb..0000000 --- a/src/main/java/com/casic/tube/frame/DataItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class DataItem { -} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java new file mode 100644 index 0000000..95d2bd4 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java @@ -0,0 +1,8 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.DataMonitorPipeOther; + +public interface IDataSentinelOtherService extends IService { + +} diff --git a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java index d6b1200..0290829 100644 --- a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java +++ b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java @@ -1,7 +1,6 @@ package com.casic.dao.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.dao.model.DataTubeOther; import com.casic.dao.model.DeviceWellView; public interface IDeviceWellViewService extends IService { diff --git a/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java new file mode 100644 index 0000000..be34f77 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java @@ -0,0 +1,16 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.BusDeviceMapper; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import org.springframework.stereotype.Service; + +@Service +public class BusDeviceServiceImpl extends ServiceImpl implements IBusDeviceService { + + @Override + public BusDevice getDeviceByCode(String devCode) { + return baseMapper.getOneByDevCode(devCode); + } +} diff --git a/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java new file mode 100644 index 0000000..0db2007 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java @@ -0,0 +1,11 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.DataSentinelOtherMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.service.IDataSentinelOtherService; +import org.springframework.stereotype.Service; + +@Service +public class DataSentinelOtherServiceImpl extends ServiceImpl implements IDataSentinelOtherService { +} diff --git a/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java new file mode 100644 index 0000000..d8c5ef2 --- /dev/null +++ b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java @@ -0,0 +1,111 @@ +package com.casic.protocol; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.CasicProtocol; +import org.springframework.stereotype.Component; + +@Component +public class CasicTubeProtocolImpl implements CasicProtocol { + @Override + public boolean checkFrame(String frame) { + boolean valid = checkFrameHeaderAndTail(frame); + if (valid) { + valid = checkFrameLength(frame); + } + + return valid; + } + + private boolean checkFrameHeaderAndTail(String frame) { + return (frame.substring(0, 2).equalsIgnoreCase("AA")) && + (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); + } + + private boolean checkFrameLength(String frame) { + String lengthStr = frame.substring(4, 7); + int length = Integer.parseInt(lengthStr); + + return frame.length() == length + 9; + } + + @Override + public String getDeviceType(String frame) { + return frame.substring(7, 9); + } + + @Override + public String getDeviceId(String frame) { + return frame.substring(9, 21); + } + + @Override + public String getManufacturerCode(String frame) { + return frame.substring(11, 13); + } + + @Override + public String getMessageType(String frame) { + return frame.substring(21, 23); + } + + @Override + public String getMessageSequence(String frame) { + return frame.substring(23, 25); + } + + @Override + public String getMessageBody(String frame) { + return frame.substring(26, frame.length() - 16); + } + + @Override + public JSONObject parseMessageBody(String messageBody) { + return JSONObject.parseObject(messageBody); + } + + @Override + public String getUptime(String frame) { + return frame.substring(frame.length() - 16, frame.length() - 2); + } + + @Override + public String buildFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append(frame.getMessageBody().toJSONString()); + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } + + @Override + public String buildReplyFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append("00"); // 消息响应类消息 消息体为00 + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/senitnel/controller/SentinelDataController.java b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java new file mode 100644 index 0000000..633c072 --- /dev/null +++ b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java @@ -0,0 +1,120 @@ +package com.casic.senitnel.controller; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.general.ConfigFrame; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import com.casic.senitnel.service.ISentinelFrameService; +import com.casic.util.aep.AepCommandSend; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Base64; +import java.util.Map; + +@Slf4j +@RestController +public class SentinelDataController { + + @Resource + private ISentinelFrameService frameService; + + @Resource + private IBusDeviceService deviceService; + + @RequestMapping("/sentinel/data/recv") + public Object dataRecv(@RequestBody Map map) { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + + JSONObject recvObj = (JSONObject) JSONObject.toJSON(map); + if (recvObj.containsKey("payload")) { + JSONObject payload = recvObj.getJSONObject("payload"); + String value = payload.getString("APPdata"); + + if (value.isEmpty()) { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } else { + byte[] baseBytes = Base64.getDecoder().decode(value); + String frameStr = new String(baseBytes); + + // 根据协议进行解析 + CasicFrame frame = frameService.dataParse(frameStr); + + if (frame != null) { + // 回复响应 + String replyFrameStr = frameService.replyMessage(frame.getDeviceCode(), frame.getSequence()); + + // 从数据库中获取master-api-key 回复响应消息 + BusDevice device = deviceService.getDeviceByCode(frame.getDeviceCode()); + if (device != null && StringUtils.isNotBlank(device.getMasterApiKey())) { + String masterApiKey = device.getMasterApiKey(); + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + + try { + int code = aepCommandSend.handleAndReply(replyFrameStr); + } catch (Exception ex) { + log.error("向设备回复响应异常:{}", ex.getMessage()); + } + } + + // 存库 + frameService.afterAction(frame); + } + + retObj.put("code", 200); + retObj.put("success", true); + } + } else { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } + + return retObj; + } + + @RequestMapping("/sentinel/config/send") + public Object configSend(@RequestBody Map map) throws Exception { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + CasicFrame cmdFrame = new ConfigFrame(); + cmdFrame.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + cmdFrame.setDeviceCode((String) map.get("devCode")); + cmdFrame.setSequence("01"); + cmdFrame.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + JSONObject messageBody = new JSONObject(); + messageBody.put("datas", map.get("cmdList")); + cmdFrame.setMessageBody(messageBody); + + String frameStr = frameService.doBuildCommand(cmdFrame); + + // TODO-LIST + // 这三个参数根据设备编号从数据库中取 + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + String masterApiKey = (String) map.get("masterApiKey"); + + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + int code = aepCommandSend.handleAndReply(frameStr); + + retObj.put("code", 200); + retObj.put("success", true); + retObj.put("AEPRetCode", code); + return retObj; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java new file mode 100644 index 0000000..368af03 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java @@ -0,0 +1,82 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; +import com.casic.dao.model.DataMonitorPipeOther; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class DataFrameNCX extends DataFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + dataItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + DataItemNCX dataItem = new DataItemNCX(); + + dataItem.setLenL(dataObj.getString("LENGL")); + dataItem.setLenR(dataObj.getString("LENGR")); + dataItem.setBat(dataObj.getString("BAT")); + dataItem.setCh4L(dataObj.getString("CH4L")); + dataItem.setCh4R(dataObj.getString("CH4R")); + dataItem.setSlope(dataObj.getString("SLOPING")); + dataItem.setDestroy(dataObj.getString("DESTROY")); + dataItem.setLeak(dataObj.getString("LEAK")); + dataItem.setDiscL(dataObj.getString("DISCL")); + dataItem.setDiscR(dataObj.getString("DISCR")); + dataItem.setVibL(dataObj.getString("VIBL")); + dataItem.setVibR(dataObj.getString("VIBR")); + dataItem.setTime(dataObj.getString("UPTIME")); + + dataItemList.add(dataItem); + } + } + + @Override + public List toDataModelList() { + List dataList = new ArrayList<>(); + for (DataItem dataItem : dataItemList) { + DataMonitorPipeOther data = new DataMonitorPipeOther(); + + data.setDevcode(getDeviceCode()); + data.setLeftLength(((DataItemNCX)dataItem).getLenL()); + data.setRightLength(((DataItemNCX)dataItem).getLenR()); + data.setLeftGas(((DataItemNCX)dataItem).getCh4L()); + data.setRightGas(((DataItemNCX)dataItem).getCh4R()); + data.setVbat(((DataItemNCX)dataItem).getBat()); + data.setPipeInclineAlarm(((DataItemNCX)dataItem).getSlope()); + data.setPipeBreakAlarm(((DataItemNCX)dataItem).getDestroy()); + data.setGasAlarm(((DataItemNCX)dataItem).getLeak()); + data.setLeftOfflineAlarm(((DataItemNCX)dataItem).getDiscL()); + data.setRightOfflineAlarm(((DataItemNCX)dataItem).getDiscR()); + data.setLeftVibrateAlarm(((DataItemNCX)dataItem).getVibL()); + data.setRightVibrateAlarm(((DataItemNCX)dataItem).getVibR()); + data.setUptime(LocalDateTime.parse(((DataItemNCX)dataItem).getTime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 采集时间 + data.setLogtime(LocalDateTime.parse(getUptime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 上报时间 + + dataList.add(data); + } + + return dataList; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java new file mode 100644 index 0000000..372ac73 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java @@ -0,0 +1,31 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.DataItem; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class DataItemNCX extends DataItem { + String lenL; // 左侧指示带长度 + String lenR; // 右侧指示带长度 + String ch4L; // 左侧甲烷浓度值 + String ch4R; // 右侧甲烷浓度值 + String bat; // 电池电压 + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String spare; // 备用 + String time; // 采集时间 + + @Override + public String toString() { + return "气体浓度值:" + "(" + ch4L + "," + ch4R + ")" + "%LEL;" + + "电池电压值:" + bat + "v;" + + "采样时间:" + time; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java new file mode 100644 index 0000000..b3bbcf4 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java @@ -0,0 +1,43 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.EventFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class EventFrameNCX extends EventFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + eventItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + EventItemNCX eventItem = new EventItemNCX(); + + eventItem.setSlope(dataObj.getString("SLOPING")); + eventItem.setDestroy(dataObj.getString("DESTROY")); + eventItem.setLeak(dataObj.getString("LEAK")); + eventItem.setDiscL(dataObj.getString("DISCL")); + eventItem.setDiscR(dataObj.getString("DISCR")); + eventItem.setVibL(dataObj.getString("VIBL")); + eventItem.setVibR(dataObj.getString("VIBR")); + eventItem.setTime(dataObj.getString("UPTIME")); + + eventItemList.add(eventItem); + } + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java new file mode 100644 index 0000000..1a560d0 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java @@ -0,0 +1,49 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.EventItem; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.commons.lang3.StringUtils; + +@EqualsAndHashCode(callSuper = true) +@Data +public class EventItemNCX extends EventItem { + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String time; // 采集时间 + + @Override + public String toString() { + String str = ""; + if (StringUtils.isNotBlank(slope) && slope.equalsIgnoreCase("1")) { + str += "[倾斜报警]"; + } + if (StringUtils.isNotBlank(destroy) && destroy.equalsIgnoreCase("1")) { + str += "[破坏报警]"; + } + if (StringUtils.isNotBlank(leak) && leak.equalsIgnoreCase("1")) { + str += "[甲烷泄漏报警]"; + } + if (StringUtils.isNotBlank(discL) && discL.equalsIgnoreCase("1")) { + str += "[左侧断线报警]"; + } + if (StringUtils.isNotBlank(discR) && discR.equalsIgnoreCase("1")) { + str += "[右侧断线报警]"; + } + if (StringUtils.isNotBlank(vibL) && vibL.equalsIgnoreCase("1")) { + str += "[左侧振动报警]"; + } + if (StringUtils.isNotBlank(vibR) && vibR.equalsIgnoreCase("1")) { + str += "[右侧振动报警]"; + } + str += "采样时间:" + time; + + return str; + + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java new file mode 100644 index 0000000..343c4d6 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java @@ -0,0 +1,37 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class InfoFrameNCX extends CasicFrame { + + String workMode; + String model; + String hwVersion; + String softVersion; + String sensorType; + + @Override + public String toString() { + return "设备编号: " + getDeviceCode() + "; " + + "设备工作模式: " + workMode + " ; " + + "设备型号: " + model + " ; " + + "版本号: " + hwVersion + ", " + softVersion + "; " + + "传感器类型: " + sensorType + " ; " + + "上报时间: " + getUptime(); + } + + @Override + public void parseMessageBody() { + workMode = getMessageBody().getString("WORKMODE"); + model = getMessageBody().getString("MODEL"); + hwVersion = getMessageBody().getString("HWVERSION"); + softVersion = getMessageBody().getString("SOFTVERSION"); + sensorType = getMessageBody().getString("SENSORTYPE"); + } +} diff --git a/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java new file mode 100644 index 0000000..e76fc86 --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java @@ -0,0 +1,14 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; + +public interface ISentinelFrameService { + + CasicFrame dataParse(String frame); + + String replyMessage(String deviceCode, String sequence); + + String doBuildCommand(CasicFrame cmd); + + void afterAction(CasicFrame frame); +} diff --git a/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java new file mode 100644 index 0000000..803ff0e --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java @@ -0,0 +1,109 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; +import com.casic.common.CasicFrameBuildFactory; +import com.casic.common.CasicProtocol; +import com.casic.common.general.DataFrame; +import com.casic.common.general.EventFrame; +import com.casic.common.general.ReplyFrame; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.model.DeviceWellView; +import com.casic.dao.service.IDataSentinelOtherService; +import com.casic.dao.service.IDeviceWellViewService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + + +@Service +@Slf4j +public class SentinelFrameServiceImpl implements ISentinelFrameService { + + @Resource + private CasicProtocol protocol; + + @Resource + IDataSentinelOtherService sentinelDataService; + + @Resource + IDeviceWellViewService deviceService; + + public CasicFrame dataParse(String frame) { + // 1. 判断帧结构 + boolean frameValid = protocol.checkFrame(frame); + if (frameValid) { + // 2. 获取帧结构中的关键字段信息 + String deviceId = protocol.getDeviceId(frame); + String deviceType = protocol.getDeviceType(frame); + String messageType = protocol.getMessageType(frame); + String messageBody = protocol.getMessageBody(frame).toUpperCase(); + String uptime = protocol.getUptime(frame); + String sequence = protocol.getMessageSequence(frame); + + String manufacturerCode = protocol.getManufacturerCode(frame); + CasicFrame sentinelFrame = CasicFrameBuildFactory.buildCasicFrame(messageType, manufacturerCode, deviceType); + + if (sentinelFrame != null) { + sentinelFrame.setDeviceCode(deviceId); + sentinelFrame.setUptime(uptime); + sentinelFrame.setMessageType(messageType); + sentinelFrame.setSequence(sequence); + + // 心跳类的消息不解析MessageBody + if (!sentinelFrame.getMessageType().equals("00")) { + sentinelFrame.setMessageBody(protocol.parseMessageBody(messageBody)); + sentinelFrame.parseMessageBody(); + } + + log.info("收到设备消息:{}", sentinelFrame); + return sentinelFrame; + } + } else { + log.error("消息帧解析异常"); + } + + return null; + } + + @Override + public String replyMessage(String deviceCode, String sequence) { + CasicFrame reply = new ReplyFrame(); + reply.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + reply.setDeviceCode(deviceCode); + reply.setSequence(sequence); + reply.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + return protocol.buildReplyFrameStr(reply); + } + + @Override + public String doBuildCommand(CasicFrame cmd) { + return protocol.buildFrameStr(cmd); + } + + @Override + public void afterAction(CasicFrame frame) { + // 数据消息帧 进行存库操作 + if (frame instanceof DataFrame) { + String devCode = frame.getDeviceCode(); + DeviceWellView devWellView = deviceService.getDeviceWellViewByDevCode(devCode); + String wellCode = ""; + if (devWellView != null) { + wellCode = devWellView.getWellCode(); + } + List dataList = ((DataFrame) frame).toDataModelList(); + if (dataList != null) { + for (Serializable item : dataList) { + DataMonitorPipeOther data = (DataMonitorPipeOther) item; + data.setWellCode(wellCode); + sentinelDataService.save(data); + } + } + } + } +} diff --git a/src/main/java/com/casic/tube/controller/TubeDataController.java b/src/main/java/com/casic/tube/controller/TubeDataController.java index 61486c5..4965449 100644 --- a/src/main/java/com/casic/tube/controller/TubeDataController.java +++ b/src/main/java/com/casic/tube/controller/TubeDataController.java @@ -2,8 +2,8 @@ import com.alibaba.fastjson.JSONObject; import com.casic.common.CasicFrame; -import com.casic.tube.frame.ConfigFrame; -import com.casic.tube.service.ITubeDataService; +import com.casic.common.general.ConfigFrame; +import com.casic.tube.service.ITubeFrameService; import com.casic.util.aep.AepCommandSend; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestBody; @@ -21,7 +21,7 @@ public class TubeDataController { @Resource - private ITubeDataService tubeDataService; + private ITubeFrameService frameService; @RequestMapping("/tube/data/recv") public Object dataRecv(@RequestBody Map map) { @@ -42,10 +42,10 @@ String frameStr = new String(baseBytes); // 根据协议进行解析 - CasicFrame frame = tubeDataService.dataParse(frameStr); + CasicFrame frame = frameService.dataParse(frameStr); // 存库 - tubeDataService.afterAction(frame); + frameService.afterAction(frame); retObj.put("code", 200); retObj.put("success", true); @@ -74,7 +74,7 @@ messageBody.put("datas", map.get("cmdList")); cmdFrame.setMessageBody(messageBody); - String frameStr = tubeDataService.doBuildCommand(cmdFrame); + String frameStr = frameService.doBuildCommand(cmdFrame); // TODO-LIST // 这三个参数根据设备编号从数据库中取 diff --git a/src/main/java/com/casic/tube/frame/ConfigFrame.java b/src/main/java/com/casic/tube/frame/ConfigFrame.java deleted file mode 100644 index 883dad6..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigFrame.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigFrame extends CasicFrame { - - public ConfigFrame() { - setSequence("01"); // 默认序号 - setControl("1"); // 默认为不需要分包 - setMessageType("52"); // 消息大类 52 = SetRequest - } -} diff --git a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java b/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java deleted file mode 100644 index a419145..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigResponseFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "03"; - final String MESSAGE_TYPE_STRING = "SetResponse"; - final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "指令序号" + getSequence() + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/DataFrame.java b/src/main/java/com/casic/tube/frame/DataFrame.java deleted file mode 100644 index 97e07b8..0000000 --- a/src/main/java/com/casic/tube/frame/DataFrame.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import com.casic.dao.model.DataTubeOther; - -import java.util.List; - -public class DataFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "02"; - final String MESSAGE_TYPE_STRING = "Data/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "数据消息/管盯"; - - public List dataItemList; - - public List toDataModelList() { - return null; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append(";"); - builder.append("上报时间:").append(getUptime()).append(";"); - for (DataItem dataItem : dataItemList) { - builder.append("["); - builder.append(dataItem); - builder.append("],"); - } - builder.deleteCharAt(builder.length() - 1); - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/DataItem.java b/src/main/java/com/casic/tube/frame/DataItem.java deleted file mode 100644 index 4e9aceb..0000000 --- a/src/main/java/com/casic/tube/frame/DataItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class DataItem { -} diff --git a/src/main/java/com/casic/tube/frame/EventFrame.java b/src/main/java/com/casic/tube/frame/EventFrame.java deleted file mode 100644 index ea800b4..0000000 --- a/src/main/java/com/casic/tube/frame/EventFrame.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -import java.util.List; - -public class EventFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "01"; - final String MESSAGE_TYPE_STRING = "Event/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "事件消息/管盯"; - - public List eventItemList; - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append("; "); - builder.append("上报时间:").append(getUptime()).append("; "); - for (EventItem eventItem : eventItemList) { - builder.append("["); - builder.append(eventItem); - builder.append("],"); - } - builder.append("}"); - return builder.toString(); - } -} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java new file mode 100644 index 0000000..95d2bd4 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java @@ -0,0 +1,8 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.DataMonitorPipeOther; + +public interface IDataSentinelOtherService extends IService { + +} diff --git a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java index d6b1200..0290829 100644 --- a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java +++ b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java @@ -1,7 +1,6 @@ package com.casic.dao.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.dao.model.DataTubeOther; import com.casic.dao.model.DeviceWellView; public interface IDeviceWellViewService extends IService { diff --git a/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java new file mode 100644 index 0000000..be34f77 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java @@ -0,0 +1,16 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.BusDeviceMapper; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import org.springframework.stereotype.Service; + +@Service +public class BusDeviceServiceImpl extends ServiceImpl implements IBusDeviceService { + + @Override + public BusDevice getDeviceByCode(String devCode) { + return baseMapper.getOneByDevCode(devCode); + } +} diff --git a/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java new file mode 100644 index 0000000..0db2007 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java @@ -0,0 +1,11 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.DataSentinelOtherMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.service.IDataSentinelOtherService; +import org.springframework.stereotype.Service; + +@Service +public class DataSentinelOtherServiceImpl extends ServiceImpl implements IDataSentinelOtherService { +} diff --git a/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java new file mode 100644 index 0000000..d8c5ef2 --- /dev/null +++ b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java @@ -0,0 +1,111 @@ +package com.casic.protocol; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.CasicProtocol; +import org.springframework.stereotype.Component; + +@Component +public class CasicTubeProtocolImpl implements CasicProtocol { + @Override + public boolean checkFrame(String frame) { + boolean valid = checkFrameHeaderAndTail(frame); + if (valid) { + valid = checkFrameLength(frame); + } + + return valid; + } + + private boolean checkFrameHeaderAndTail(String frame) { + return (frame.substring(0, 2).equalsIgnoreCase("AA")) && + (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); + } + + private boolean checkFrameLength(String frame) { + String lengthStr = frame.substring(4, 7); + int length = Integer.parseInt(lengthStr); + + return frame.length() == length + 9; + } + + @Override + public String getDeviceType(String frame) { + return frame.substring(7, 9); + } + + @Override + public String getDeviceId(String frame) { + return frame.substring(9, 21); + } + + @Override + public String getManufacturerCode(String frame) { + return frame.substring(11, 13); + } + + @Override + public String getMessageType(String frame) { + return frame.substring(21, 23); + } + + @Override + public String getMessageSequence(String frame) { + return frame.substring(23, 25); + } + + @Override + public String getMessageBody(String frame) { + return frame.substring(26, frame.length() - 16); + } + + @Override + public JSONObject parseMessageBody(String messageBody) { + return JSONObject.parseObject(messageBody); + } + + @Override + public String getUptime(String frame) { + return frame.substring(frame.length() - 16, frame.length() - 2); + } + + @Override + public String buildFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append(frame.getMessageBody().toJSONString()); + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } + + @Override + public String buildReplyFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append("00"); // 消息响应类消息 消息体为00 + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/senitnel/controller/SentinelDataController.java b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java new file mode 100644 index 0000000..633c072 --- /dev/null +++ b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java @@ -0,0 +1,120 @@ +package com.casic.senitnel.controller; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.general.ConfigFrame; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import com.casic.senitnel.service.ISentinelFrameService; +import com.casic.util.aep.AepCommandSend; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Base64; +import java.util.Map; + +@Slf4j +@RestController +public class SentinelDataController { + + @Resource + private ISentinelFrameService frameService; + + @Resource + private IBusDeviceService deviceService; + + @RequestMapping("/sentinel/data/recv") + public Object dataRecv(@RequestBody Map map) { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + + JSONObject recvObj = (JSONObject) JSONObject.toJSON(map); + if (recvObj.containsKey("payload")) { + JSONObject payload = recvObj.getJSONObject("payload"); + String value = payload.getString("APPdata"); + + if (value.isEmpty()) { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } else { + byte[] baseBytes = Base64.getDecoder().decode(value); + String frameStr = new String(baseBytes); + + // 根据协议进行解析 + CasicFrame frame = frameService.dataParse(frameStr); + + if (frame != null) { + // 回复响应 + String replyFrameStr = frameService.replyMessage(frame.getDeviceCode(), frame.getSequence()); + + // 从数据库中获取master-api-key 回复响应消息 + BusDevice device = deviceService.getDeviceByCode(frame.getDeviceCode()); + if (device != null && StringUtils.isNotBlank(device.getMasterApiKey())) { + String masterApiKey = device.getMasterApiKey(); + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + + try { + int code = aepCommandSend.handleAndReply(replyFrameStr); + } catch (Exception ex) { + log.error("向设备回复响应异常:{}", ex.getMessage()); + } + } + + // 存库 + frameService.afterAction(frame); + } + + retObj.put("code", 200); + retObj.put("success", true); + } + } else { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } + + return retObj; + } + + @RequestMapping("/sentinel/config/send") + public Object configSend(@RequestBody Map map) throws Exception { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + CasicFrame cmdFrame = new ConfigFrame(); + cmdFrame.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + cmdFrame.setDeviceCode((String) map.get("devCode")); + cmdFrame.setSequence("01"); + cmdFrame.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + JSONObject messageBody = new JSONObject(); + messageBody.put("datas", map.get("cmdList")); + cmdFrame.setMessageBody(messageBody); + + String frameStr = frameService.doBuildCommand(cmdFrame); + + // TODO-LIST + // 这三个参数根据设备编号从数据库中取 + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + String masterApiKey = (String) map.get("masterApiKey"); + + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + int code = aepCommandSend.handleAndReply(frameStr); + + retObj.put("code", 200); + retObj.put("success", true); + retObj.put("AEPRetCode", code); + return retObj; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java new file mode 100644 index 0000000..368af03 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java @@ -0,0 +1,82 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; +import com.casic.dao.model.DataMonitorPipeOther; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class DataFrameNCX extends DataFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + dataItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + DataItemNCX dataItem = new DataItemNCX(); + + dataItem.setLenL(dataObj.getString("LENGL")); + dataItem.setLenR(dataObj.getString("LENGR")); + dataItem.setBat(dataObj.getString("BAT")); + dataItem.setCh4L(dataObj.getString("CH4L")); + dataItem.setCh4R(dataObj.getString("CH4R")); + dataItem.setSlope(dataObj.getString("SLOPING")); + dataItem.setDestroy(dataObj.getString("DESTROY")); + dataItem.setLeak(dataObj.getString("LEAK")); + dataItem.setDiscL(dataObj.getString("DISCL")); + dataItem.setDiscR(dataObj.getString("DISCR")); + dataItem.setVibL(dataObj.getString("VIBL")); + dataItem.setVibR(dataObj.getString("VIBR")); + dataItem.setTime(dataObj.getString("UPTIME")); + + dataItemList.add(dataItem); + } + } + + @Override + public List toDataModelList() { + List dataList = new ArrayList<>(); + for (DataItem dataItem : dataItemList) { + DataMonitorPipeOther data = new DataMonitorPipeOther(); + + data.setDevcode(getDeviceCode()); + data.setLeftLength(((DataItemNCX)dataItem).getLenL()); + data.setRightLength(((DataItemNCX)dataItem).getLenR()); + data.setLeftGas(((DataItemNCX)dataItem).getCh4L()); + data.setRightGas(((DataItemNCX)dataItem).getCh4R()); + data.setVbat(((DataItemNCX)dataItem).getBat()); + data.setPipeInclineAlarm(((DataItemNCX)dataItem).getSlope()); + data.setPipeBreakAlarm(((DataItemNCX)dataItem).getDestroy()); + data.setGasAlarm(((DataItemNCX)dataItem).getLeak()); + data.setLeftOfflineAlarm(((DataItemNCX)dataItem).getDiscL()); + data.setRightOfflineAlarm(((DataItemNCX)dataItem).getDiscR()); + data.setLeftVibrateAlarm(((DataItemNCX)dataItem).getVibL()); + data.setRightVibrateAlarm(((DataItemNCX)dataItem).getVibR()); + data.setUptime(LocalDateTime.parse(((DataItemNCX)dataItem).getTime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 采集时间 + data.setLogtime(LocalDateTime.parse(getUptime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 上报时间 + + dataList.add(data); + } + + return dataList; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java new file mode 100644 index 0000000..372ac73 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java @@ -0,0 +1,31 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.DataItem; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class DataItemNCX extends DataItem { + String lenL; // 左侧指示带长度 + String lenR; // 右侧指示带长度 + String ch4L; // 左侧甲烷浓度值 + String ch4R; // 右侧甲烷浓度值 + String bat; // 电池电压 + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String spare; // 备用 + String time; // 采集时间 + + @Override + public String toString() { + return "气体浓度值:" + "(" + ch4L + "," + ch4R + ")" + "%LEL;" + + "电池电压值:" + bat + "v;" + + "采样时间:" + time; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java new file mode 100644 index 0000000..b3bbcf4 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java @@ -0,0 +1,43 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.EventFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class EventFrameNCX extends EventFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + eventItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + EventItemNCX eventItem = new EventItemNCX(); + + eventItem.setSlope(dataObj.getString("SLOPING")); + eventItem.setDestroy(dataObj.getString("DESTROY")); + eventItem.setLeak(dataObj.getString("LEAK")); + eventItem.setDiscL(dataObj.getString("DISCL")); + eventItem.setDiscR(dataObj.getString("DISCR")); + eventItem.setVibL(dataObj.getString("VIBL")); + eventItem.setVibR(dataObj.getString("VIBR")); + eventItem.setTime(dataObj.getString("UPTIME")); + + eventItemList.add(eventItem); + } + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java new file mode 100644 index 0000000..1a560d0 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java @@ -0,0 +1,49 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.EventItem; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.commons.lang3.StringUtils; + +@EqualsAndHashCode(callSuper = true) +@Data +public class EventItemNCX extends EventItem { + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String time; // 采集时间 + + @Override + public String toString() { + String str = ""; + if (StringUtils.isNotBlank(slope) && slope.equalsIgnoreCase("1")) { + str += "[倾斜报警]"; + } + if (StringUtils.isNotBlank(destroy) && destroy.equalsIgnoreCase("1")) { + str += "[破坏报警]"; + } + if (StringUtils.isNotBlank(leak) && leak.equalsIgnoreCase("1")) { + str += "[甲烷泄漏报警]"; + } + if (StringUtils.isNotBlank(discL) && discL.equalsIgnoreCase("1")) { + str += "[左侧断线报警]"; + } + if (StringUtils.isNotBlank(discR) && discR.equalsIgnoreCase("1")) { + str += "[右侧断线报警]"; + } + if (StringUtils.isNotBlank(vibL) && vibL.equalsIgnoreCase("1")) { + str += "[左侧振动报警]"; + } + if (StringUtils.isNotBlank(vibR) && vibR.equalsIgnoreCase("1")) { + str += "[右侧振动报警]"; + } + str += "采样时间:" + time; + + return str; + + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java new file mode 100644 index 0000000..343c4d6 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java @@ -0,0 +1,37 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class InfoFrameNCX extends CasicFrame { + + String workMode; + String model; + String hwVersion; + String softVersion; + String sensorType; + + @Override + public String toString() { + return "设备编号: " + getDeviceCode() + "; " + + "设备工作模式: " + workMode + " ; " + + "设备型号: " + model + " ; " + + "版本号: " + hwVersion + ", " + softVersion + "; " + + "传感器类型: " + sensorType + " ; " + + "上报时间: " + getUptime(); + } + + @Override + public void parseMessageBody() { + workMode = getMessageBody().getString("WORKMODE"); + model = getMessageBody().getString("MODEL"); + hwVersion = getMessageBody().getString("HWVERSION"); + softVersion = getMessageBody().getString("SOFTVERSION"); + sensorType = getMessageBody().getString("SENSORTYPE"); + } +} diff --git a/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java new file mode 100644 index 0000000..e76fc86 --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java @@ -0,0 +1,14 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; + +public interface ISentinelFrameService { + + CasicFrame dataParse(String frame); + + String replyMessage(String deviceCode, String sequence); + + String doBuildCommand(CasicFrame cmd); + + void afterAction(CasicFrame frame); +} diff --git a/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java new file mode 100644 index 0000000..803ff0e --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java @@ -0,0 +1,109 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; +import com.casic.common.CasicFrameBuildFactory; +import com.casic.common.CasicProtocol; +import com.casic.common.general.DataFrame; +import com.casic.common.general.EventFrame; +import com.casic.common.general.ReplyFrame; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.model.DeviceWellView; +import com.casic.dao.service.IDataSentinelOtherService; +import com.casic.dao.service.IDeviceWellViewService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + + +@Service +@Slf4j +public class SentinelFrameServiceImpl implements ISentinelFrameService { + + @Resource + private CasicProtocol protocol; + + @Resource + IDataSentinelOtherService sentinelDataService; + + @Resource + IDeviceWellViewService deviceService; + + public CasicFrame dataParse(String frame) { + // 1. 判断帧结构 + boolean frameValid = protocol.checkFrame(frame); + if (frameValid) { + // 2. 获取帧结构中的关键字段信息 + String deviceId = protocol.getDeviceId(frame); + String deviceType = protocol.getDeviceType(frame); + String messageType = protocol.getMessageType(frame); + String messageBody = protocol.getMessageBody(frame).toUpperCase(); + String uptime = protocol.getUptime(frame); + String sequence = protocol.getMessageSequence(frame); + + String manufacturerCode = protocol.getManufacturerCode(frame); + CasicFrame sentinelFrame = CasicFrameBuildFactory.buildCasicFrame(messageType, manufacturerCode, deviceType); + + if (sentinelFrame != null) { + sentinelFrame.setDeviceCode(deviceId); + sentinelFrame.setUptime(uptime); + sentinelFrame.setMessageType(messageType); + sentinelFrame.setSequence(sequence); + + // 心跳类的消息不解析MessageBody + if (!sentinelFrame.getMessageType().equals("00")) { + sentinelFrame.setMessageBody(protocol.parseMessageBody(messageBody)); + sentinelFrame.parseMessageBody(); + } + + log.info("收到设备消息:{}", sentinelFrame); + return sentinelFrame; + } + } else { + log.error("消息帧解析异常"); + } + + return null; + } + + @Override + public String replyMessage(String deviceCode, String sequence) { + CasicFrame reply = new ReplyFrame(); + reply.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + reply.setDeviceCode(deviceCode); + reply.setSequence(sequence); + reply.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + return protocol.buildReplyFrameStr(reply); + } + + @Override + public String doBuildCommand(CasicFrame cmd) { + return protocol.buildFrameStr(cmd); + } + + @Override + public void afterAction(CasicFrame frame) { + // 数据消息帧 进行存库操作 + if (frame instanceof DataFrame) { + String devCode = frame.getDeviceCode(); + DeviceWellView devWellView = deviceService.getDeviceWellViewByDevCode(devCode); + String wellCode = ""; + if (devWellView != null) { + wellCode = devWellView.getWellCode(); + } + List dataList = ((DataFrame) frame).toDataModelList(); + if (dataList != null) { + for (Serializable item : dataList) { + DataMonitorPipeOther data = (DataMonitorPipeOther) item; + data.setWellCode(wellCode); + sentinelDataService.save(data); + } + } + } + } +} diff --git a/src/main/java/com/casic/tube/controller/TubeDataController.java b/src/main/java/com/casic/tube/controller/TubeDataController.java index 61486c5..4965449 100644 --- a/src/main/java/com/casic/tube/controller/TubeDataController.java +++ b/src/main/java/com/casic/tube/controller/TubeDataController.java @@ -2,8 +2,8 @@ import com.alibaba.fastjson.JSONObject; import com.casic.common.CasicFrame; -import com.casic.tube.frame.ConfigFrame; -import com.casic.tube.service.ITubeDataService; +import com.casic.common.general.ConfigFrame; +import com.casic.tube.service.ITubeFrameService; import com.casic.util.aep.AepCommandSend; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestBody; @@ -21,7 +21,7 @@ public class TubeDataController { @Resource - private ITubeDataService tubeDataService; + private ITubeFrameService frameService; @RequestMapping("/tube/data/recv") public Object dataRecv(@RequestBody Map map) { @@ -42,10 +42,10 @@ String frameStr = new String(baseBytes); // 根据协议进行解析 - CasicFrame frame = tubeDataService.dataParse(frameStr); + CasicFrame frame = frameService.dataParse(frameStr); // 存库 - tubeDataService.afterAction(frame); + frameService.afterAction(frame); retObj.put("code", 200); retObj.put("success", true); @@ -74,7 +74,7 @@ messageBody.put("datas", map.get("cmdList")); cmdFrame.setMessageBody(messageBody); - String frameStr = tubeDataService.doBuildCommand(cmdFrame); + String frameStr = frameService.doBuildCommand(cmdFrame); // TODO-LIST // 这三个参数根据设备编号从数据库中取 diff --git a/src/main/java/com/casic/tube/frame/ConfigFrame.java b/src/main/java/com/casic/tube/frame/ConfigFrame.java deleted file mode 100644 index 883dad6..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigFrame.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigFrame extends CasicFrame { - - public ConfigFrame() { - setSequence("01"); // 默认序号 - setControl("1"); // 默认为不需要分包 - setMessageType("52"); // 消息大类 52 = SetRequest - } -} diff --git a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java b/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java deleted file mode 100644 index a419145..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigResponseFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "03"; - final String MESSAGE_TYPE_STRING = "SetResponse"; - final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "指令序号" + getSequence() + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/DataFrame.java b/src/main/java/com/casic/tube/frame/DataFrame.java deleted file mode 100644 index 97e07b8..0000000 --- a/src/main/java/com/casic/tube/frame/DataFrame.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import com.casic.dao.model.DataTubeOther; - -import java.util.List; - -public class DataFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "02"; - final String MESSAGE_TYPE_STRING = "Data/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "数据消息/管盯"; - - public List dataItemList; - - public List toDataModelList() { - return null; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append(";"); - builder.append("上报时间:").append(getUptime()).append(";"); - for (DataItem dataItem : dataItemList) { - builder.append("["); - builder.append(dataItem); - builder.append("],"); - } - builder.deleteCharAt(builder.length() - 1); - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/DataItem.java b/src/main/java/com/casic/tube/frame/DataItem.java deleted file mode 100644 index 4e9aceb..0000000 --- a/src/main/java/com/casic/tube/frame/DataItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class DataItem { -} diff --git a/src/main/java/com/casic/tube/frame/EventFrame.java b/src/main/java/com/casic/tube/frame/EventFrame.java deleted file mode 100644 index ea800b4..0000000 --- a/src/main/java/com/casic/tube/frame/EventFrame.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -import java.util.List; - -public class EventFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "01"; - final String MESSAGE_TYPE_STRING = "Event/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "事件消息/管盯"; - - public List eventItemList; - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append("; "); - builder.append("上报时间:").append(getUptime()).append("; "); - for (EventItem eventItem : eventItemList) { - builder.append("["); - builder.append(eventItem); - builder.append("],"); - } - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/EventItem.java b/src/main/java/com/casic/tube/frame/EventItem.java deleted file mode 100644 index a1245bf..0000000 --- a/src/main/java/com/casic/tube/frame/EventItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class EventItem { -} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java new file mode 100644 index 0000000..95d2bd4 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java @@ -0,0 +1,8 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.DataMonitorPipeOther; + +public interface IDataSentinelOtherService extends IService { + +} diff --git a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java index d6b1200..0290829 100644 --- a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java +++ b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java @@ -1,7 +1,6 @@ package com.casic.dao.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.dao.model.DataTubeOther; import com.casic.dao.model.DeviceWellView; public interface IDeviceWellViewService extends IService { diff --git a/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java new file mode 100644 index 0000000..be34f77 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java @@ -0,0 +1,16 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.BusDeviceMapper; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import org.springframework.stereotype.Service; + +@Service +public class BusDeviceServiceImpl extends ServiceImpl implements IBusDeviceService { + + @Override + public BusDevice getDeviceByCode(String devCode) { + return baseMapper.getOneByDevCode(devCode); + } +} diff --git a/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java new file mode 100644 index 0000000..0db2007 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java @@ -0,0 +1,11 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.DataSentinelOtherMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.service.IDataSentinelOtherService; +import org.springframework.stereotype.Service; + +@Service +public class DataSentinelOtherServiceImpl extends ServiceImpl implements IDataSentinelOtherService { +} diff --git a/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java new file mode 100644 index 0000000..d8c5ef2 --- /dev/null +++ b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java @@ -0,0 +1,111 @@ +package com.casic.protocol; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.CasicProtocol; +import org.springframework.stereotype.Component; + +@Component +public class CasicTubeProtocolImpl implements CasicProtocol { + @Override + public boolean checkFrame(String frame) { + boolean valid = checkFrameHeaderAndTail(frame); + if (valid) { + valid = checkFrameLength(frame); + } + + return valid; + } + + private boolean checkFrameHeaderAndTail(String frame) { + return (frame.substring(0, 2).equalsIgnoreCase("AA")) && + (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); + } + + private boolean checkFrameLength(String frame) { + String lengthStr = frame.substring(4, 7); + int length = Integer.parseInt(lengthStr); + + return frame.length() == length + 9; + } + + @Override + public String getDeviceType(String frame) { + return frame.substring(7, 9); + } + + @Override + public String getDeviceId(String frame) { + return frame.substring(9, 21); + } + + @Override + public String getManufacturerCode(String frame) { + return frame.substring(11, 13); + } + + @Override + public String getMessageType(String frame) { + return frame.substring(21, 23); + } + + @Override + public String getMessageSequence(String frame) { + return frame.substring(23, 25); + } + + @Override + public String getMessageBody(String frame) { + return frame.substring(26, frame.length() - 16); + } + + @Override + public JSONObject parseMessageBody(String messageBody) { + return JSONObject.parseObject(messageBody); + } + + @Override + public String getUptime(String frame) { + return frame.substring(frame.length() - 16, frame.length() - 2); + } + + @Override + public String buildFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append(frame.getMessageBody().toJSONString()); + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } + + @Override + public String buildReplyFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append("00"); // 消息响应类消息 消息体为00 + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/senitnel/controller/SentinelDataController.java b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java new file mode 100644 index 0000000..633c072 --- /dev/null +++ b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java @@ -0,0 +1,120 @@ +package com.casic.senitnel.controller; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.general.ConfigFrame; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import com.casic.senitnel.service.ISentinelFrameService; +import com.casic.util.aep.AepCommandSend; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Base64; +import java.util.Map; + +@Slf4j +@RestController +public class SentinelDataController { + + @Resource + private ISentinelFrameService frameService; + + @Resource + private IBusDeviceService deviceService; + + @RequestMapping("/sentinel/data/recv") + public Object dataRecv(@RequestBody Map map) { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + + JSONObject recvObj = (JSONObject) JSONObject.toJSON(map); + if (recvObj.containsKey("payload")) { + JSONObject payload = recvObj.getJSONObject("payload"); + String value = payload.getString("APPdata"); + + if (value.isEmpty()) { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } else { + byte[] baseBytes = Base64.getDecoder().decode(value); + String frameStr = new String(baseBytes); + + // 根据协议进行解析 + CasicFrame frame = frameService.dataParse(frameStr); + + if (frame != null) { + // 回复响应 + String replyFrameStr = frameService.replyMessage(frame.getDeviceCode(), frame.getSequence()); + + // 从数据库中获取master-api-key 回复响应消息 + BusDevice device = deviceService.getDeviceByCode(frame.getDeviceCode()); + if (device != null && StringUtils.isNotBlank(device.getMasterApiKey())) { + String masterApiKey = device.getMasterApiKey(); + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + + try { + int code = aepCommandSend.handleAndReply(replyFrameStr); + } catch (Exception ex) { + log.error("向设备回复响应异常:{}", ex.getMessage()); + } + } + + // 存库 + frameService.afterAction(frame); + } + + retObj.put("code", 200); + retObj.put("success", true); + } + } else { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } + + return retObj; + } + + @RequestMapping("/sentinel/config/send") + public Object configSend(@RequestBody Map map) throws Exception { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + CasicFrame cmdFrame = new ConfigFrame(); + cmdFrame.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + cmdFrame.setDeviceCode((String) map.get("devCode")); + cmdFrame.setSequence("01"); + cmdFrame.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + JSONObject messageBody = new JSONObject(); + messageBody.put("datas", map.get("cmdList")); + cmdFrame.setMessageBody(messageBody); + + String frameStr = frameService.doBuildCommand(cmdFrame); + + // TODO-LIST + // 这三个参数根据设备编号从数据库中取 + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + String masterApiKey = (String) map.get("masterApiKey"); + + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + int code = aepCommandSend.handleAndReply(frameStr); + + retObj.put("code", 200); + retObj.put("success", true); + retObj.put("AEPRetCode", code); + return retObj; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java new file mode 100644 index 0000000..368af03 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java @@ -0,0 +1,82 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; +import com.casic.dao.model.DataMonitorPipeOther; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class DataFrameNCX extends DataFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + dataItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + DataItemNCX dataItem = new DataItemNCX(); + + dataItem.setLenL(dataObj.getString("LENGL")); + dataItem.setLenR(dataObj.getString("LENGR")); + dataItem.setBat(dataObj.getString("BAT")); + dataItem.setCh4L(dataObj.getString("CH4L")); + dataItem.setCh4R(dataObj.getString("CH4R")); + dataItem.setSlope(dataObj.getString("SLOPING")); + dataItem.setDestroy(dataObj.getString("DESTROY")); + dataItem.setLeak(dataObj.getString("LEAK")); + dataItem.setDiscL(dataObj.getString("DISCL")); + dataItem.setDiscR(dataObj.getString("DISCR")); + dataItem.setVibL(dataObj.getString("VIBL")); + dataItem.setVibR(dataObj.getString("VIBR")); + dataItem.setTime(dataObj.getString("UPTIME")); + + dataItemList.add(dataItem); + } + } + + @Override + public List toDataModelList() { + List dataList = new ArrayList<>(); + for (DataItem dataItem : dataItemList) { + DataMonitorPipeOther data = new DataMonitorPipeOther(); + + data.setDevcode(getDeviceCode()); + data.setLeftLength(((DataItemNCX)dataItem).getLenL()); + data.setRightLength(((DataItemNCX)dataItem).getLenR()); + data.setLeftGas(((DataItemNCX)dataItem).getCh4L()); + data.setRightGas(((DataItemNCX)dataItem).getCh4R()); + data.setVbat(((DataItemNCX)dataItem).getBat()); + data.setPipeInclineAlarm(((DataItemNCX)dataItem).getSlope()); + data.setPipeBreakAlarm(((DataItemNCX)dataItem).getDestroy()); + data.setGasAlarm(((DataItemNCX)dataItem).getLeak()); + data.setLeftOfflineAlarm(((DataItemNCX)dataItem).getDiscL()); + data.setRightOfflineAlarm(((DataItemNCX)dataItem).getDiscR()); + data.setLeftVibrateAlarm(((DataItemNCX)dataItem).getVibL()); + data.setRightVibrateAlarm(((DataItemNCX)dataItem).getVibR()); + data.setUptime(LocalDateTime.parse(((DataItemNCX)dataItem).getTime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 采集时间 + data.setLogtime(LocalDateTime.parse(getUptime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 上报时间 + + dataList.add(data); + } + + return dataList; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java new file mode 100644 index 0000000..372ac73 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java @@ -0,0 +1,31 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.DataItem; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class DataItemNCX extends DataItem { + String lenL; // 左侧指示带长度 + String lenR; // 右侧指示带长度 + String ch4L; // 左侧甲烷浓度值 + String ch4R; // 右侧甲烷浓度值 + String bat; // 电池电压 + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String spare; // 备用 + String time; // 采集时间 + + @Override + public String toString() { + return "气体浓度值:" + "(" + ch4L + "," + ch4R + ")" + "%LEL;" + + "电池电压值:" + bat + "v;" + + "采样时间:" + time; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java new file mode 100644 index 0000000..b3bbcf4 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java @@ -0,0 +1,43 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.EventFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class EventFrameNCX extends EventFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + eventItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + EventItemNCX eventItem = new EventItemNCX(); + + eventItem.setSlope(dataObj.getString("SLOPING")); + eventItem.setDestroy(dataObj.getString("DESTROY")); + eventItem.setLeak(dataObj.getString("LEAK")); + eventItem.setDiscL(dataObj.getString("DISCL")); + eventItem.setDiscR(dataObj.getString("DISCR")); + eventItem.setVibL(dataObj.getString("VIBL")); + eventItem.setVibR(dataObj.getString("VIBR")); + eventItem.setTime(dataObj.getString("UPTIME")); + + eventItemList.add(eventItem); + } + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java new file mode 100644 index 0000000..1a560d0 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java @@ -0,0 +1,49 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.EventItem; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.commons.lang3.StringUtils; + +@EqualsAndHashCode(callSuper = true) +@Data +public class EventItemNCX extends EventItem { + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String time; // 采集时间 + + @Override + public String toString() { + String str = ""; + if (StringUtils.isNotBlank(slope) && slope.equalsIgnoreCase("1")) { + str += "[倾斜报警]"; + } + if (StringUtils.isNotBlank(destroy) && destroy.equalsIgnoreCase("1")) { + str += "[破坏报警]"; + } + if (StringUtils.isNotBlank(leak) && leak.equalsIgnoreCase("1")) { + str += "[甲烷泄漏报警]"; + } + if (StringUtils.isNotBlank(discL) && discL.equalsIgnoreCase("1")) { + str += "[左侧断线报警]"; + } + if (StringUtils.isNotBlank(discR) && discR.equalsIgnoreCase("1")) { + str += "[右侧断线报警]"; + } + if (StringUtils.isNotBlank(vibL) && vibL.equalsIgnoreCase("1")) { + str += "[左侧振动报警]"; + } + if (StringUtils.isNotBlank(vibR) && vibR.equalsIgnoreCase("1")) { + str += "[右侧振动报警]"; + } + str += "采样时间:" + time; + + return str; + + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java new file mode 100644 index 0000000..343c4d6 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java @@ -0,0 +1,37 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class InfoFrameNCX extends CasicFrame { + + String workMode; + String model; + String hwVersion; + String softVersion; + String sensorType; + + @Override + public String toString() { + return "设备编号: " + getDeviceCode() + "; " + + "设备工作模式: " + workMode + " ; " + + "设备型号: " + model + " ; " + + "版本号: " + hwVersion + ", " + softVersion + "; " + + "传感器类型: " + sensorType + " ; " + + "上报时间: " + getUptime(); + } + + @Override + public void parseMessageBody() { + workMode = getMessageBody().getString("WORKMODE"); + model = getMessageBody().getString("MODEL"); + hwVersion = getMessageBody().getString("HWVERSION"); + softVersion = getMessageBody().getString("SOFTVERSION"); + sensorType = getMessageBody().getString("SENSORTYPE"); + } +} diff --git a/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java new file mode 100644 index 0000000..e76fc86 --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java @@ -0,0 +1,14 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; + +public interface ISentinelFrameService { + + CasicFrame dataParse(String frame); + + String replyMessage(String deviceCode, String sequence); + + String doBuildCommand(CasicFrame cmd); + + void afterAction(CasicFrame frame); +} diff --git a/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java new file mode 100644 index 0000000..803ff0e --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java @@ -0,0 +1,109 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; +import com.casic.common.CasicFrameBuildFactory; +import com.casic.common.CasicProtocol; +import com.casic.common.general.DataFrame; +import com.casic.common.general.EventFrame; +import com.casic.common.general.ReplyFrame; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.model.DeviceWellView; +import com.casic.dao.service.IDataSentinelOtherService; +import com.casic.dao.service.IDeviceWellViewService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + + +@Service +@Slf4j +public class SentinelFrameServiceImpl implements ISentinelFrameService { + + @Resource + private CasicProtocol protocol; + + @Resource + IDataSentinelOtherService sentinelDataService; + + @Resource + IDeviceWellViewService deviceService; + + public CasicFrame dataParse(String frame) { + // 1. 判断帧结构 + boolean frameValid = protocol.checkFrame(frame); + if (frameValid) { + // 2. 获取帧结构中的关键字段信息 + String deviceId = protocol.getDeviceId(frame); + String deviceType = protocol.getDeviceType(frame); + String messageType = protocol.getMessageType(frame); + String messageBody = protocol.getMessageBody(frame).toUpperCase(); + String uptime = protocol.getUptime(frame); + String sequence = protocol.getMessageSequence(frame); + + String manufacturerCode = protocol.getManufacturerCode(frame); + CasicFrame sentinelFrame = CasicFrameBuildFactory.buildCasicFrame(messageType, manufacturerCode, deviceType); + + if (sentinelFrame != null) { + sentinelFrame.setDeviceCode(deviceId); + sentinelFrame.setUptime(uptime); + sentinelFrame.setMessageType(messageType); + sentinelFrame.setSequence(sequence); + + // 心跳类的消息不解析MessageBody + if (!sentinelFrame.getMessageType().equals("00")) { + sentinelFrame.setMessageBody(protocol.parseMessageBody(messageBody)); + sentinelFrame.parseMessageBody(); + } + + log.info("收到设备消息:{}", sentinelFrame); + return sentinelFrame; + } + } else { + log.error("消息帧解析异常"); + } + + return null; + } + + @Override + public String replyMessage(String deviceCode, String sequence) { + CasicFrame reply = new ReplyFrame(); + reply.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + reply.setDeviceCode(deviceCode); + reply.setSequence(sequence); + reply.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + return protocol.buildReplyFrameStr(reply); + } + + @Override + public String doBuildCommand(CasicFrame cmd) { + return protocol.buildFrameStr(cmd); + } + + @Override + public void afterAction(CasicFrame frame) { + // 数据消息帧 进行存库操作 + if (frame instanceof DataFrame) { + String devCode = frame.getDeviceCode(); + DeviceWellView devWellView = deviceService.getDeviceWellViewByDevCode(devCode); + String wellCode = ""; + if (devWellView != null) { + wellCode = devWellView.getWellCode(); + } + List dataList = ((DataFrame) frame).toDataModelList(); + if (dataList != null) { + for (Serializable item : dataList) { + DataMonitorPipeOther data = (DataMonitorPipeOther) item; + data.setWellCode(wellCode); + sentinelDataService.save(data); + } + } + } + } +} diff --git a/src/main/java/com/casic/tube/controller/TubeDataController.java b/src/main/java/com/casic/tube/controller/TubeDataController.java index 61486c5..4965449 100644 --- a/src/main/java/com/casic/tube/controller/TubeDataController.java +++ b/src/main/java/com/casic/tube/controller/TubeDataController.java @@ -2,8 +2,8 @@ import com.alibaba.fastjson.JSONObject; import com.casic.common.CasicFrame; -import com.casic.tube.frame.ConfigFrame; -import com.casic.tube.service.ITubeDataService; +import com.casic.common.general.ConfigFrame; +import com.casic.tube.service.ITubeFrameService; import com.casic.util.aep.AepCommandSend; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestBody; @@ -21,7 +21,7 @@ public class TubeDataController { @Resource - private ITubeDataService tubeDataService; + private ITubeFrameService frameService; @RequestMapping("/tube/data/recv") public Object dataRecv(@RequestBody Map map) { @@ -42,10 +42,10 @@ String frameStr = new String(baseBytes); // 根据协议进行解析 - CasicFrame frame = tubeDataService.dataParse(frameStr); + CasicFrame frame = frameService.dataParse(frameStr); // 存库 - tubeDataService.afterAction(frame); + frameService.afterAction(frame); retObj.put("code", 200); retObj.put("success", true); @@ -74,7 +74,7 @@ messageBody.put("datas", map.get("cmdList")); cmdFrame.setMessageBody(messageBody); - String frameStr = tubeDataService.doBuildCommand(cmdFrame); + String frameStr = frameService.doBuildCommand(cmdFrame); // TODO-LIST // 这三个参数根据设备编号从数据库中取 diff --git a/src/main/java/com/casic/tube/frame/ConfigFrame.java b/src/main/java/com/casic/tube/frame/ConfigFrame.java deleted file mode 100644 index 883dad6..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigFrame.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigFrame extends CasicFrame { - - public ConfigFrame() { - setSequence("01"); // 默认序号 - setControl("1"); // 默认为不需要分包 - setMessageType("52"); // 消息大类 52 = SetRequest - } -} diff --git a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java b/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java deleted file mode 100644 index a419145..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigResponseFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "03"; - final String MESSAGE_TYPE_STRING = "SetResponse"; - final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "指令序号" + getSequence() + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/DataFrame.java b/src/main/java/com/casic/tube/frame/DataFrame.java deleted file mode 100644 index 97e07b8..0000000 --- a/src/main/java/com/casic/tube/frame/DataFrame.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import com.casic.dao.model.DataTubeOther; - -import java.util.List; - -public class DataFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "02"; - final String MESSAGE_TYPE_STRING = "Data/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "数据消息/管盯"; - - public List dataItemList; - - public List toDataModelList() { - return null; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append(";"); - builder.append("上报时间:").append(getUptime()).append(";"); - for (DataItem dataItem : dataItemList) { - builder.append("["); - builder.append(dataItem); - builder.append("],"); - } - builder.deleteCharAt(builder.length() - 1); - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/DataItem.java b/src/main/java/com/casic/tube/frame/DataItem.java deleted file mode 100644 index 4e9aceb..0000000 --- a/src/main/java/com/casic/tube/frame/DataItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class DataItem { -} diff --git a/src/main/java/com/casic/tube/frame/EventFrame.java b/src/main/java/com/casic/tube/frame/EventFrame.java deleted file mode 100644 index ea800b4..0000000 --- a/src/main/java/com/casic/tube/frame/EventFrame.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -import java.util.List; - -public class EventFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "01"; - final String MESSAGE_TYPE_STRING = "Event/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "事件消息/管盯"; - - public List eventItemList; - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append("; "); - builder.append("上报时间:").append(getUptime()).append("; "); - for (EventItem eventItem : eventItemList) { - builder.append("["); - builder.append(eventItem); - builder.append("],"); - } - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/EventItem.java b/src/main/java/com/casic/tube/frame/EventItem.java deleted file mode 100644 index a1245bf..0000000 --- a/src/main/java/com/casic/tube/frame/EventItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class EventItem { -} diff --git a/src/main/java/com/casic/tube/frame/HeartFrame.java b/src/main/java/com/casic/tube/frame/HeartFrame.java deleted file mode 100644 index af7e7a6..0000000 --- a/src/main/java/com/casic/tube/frame/HeartFrame.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; - -@Data -public class HeartFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "00"; - final String MESSAGE_TYPE_STRING = "OnlineRequest"; - final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java new file mode 100644 index 0000000..95d2bd4 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java @@ -0,0 +1,8 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.DataMonitorPipeOther; + +public interface IDataSentinelOtherService extends IService { + +} diff --git a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java index d6b1200..0290829 100644 --- a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java +++ b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java @@ -1,7 +1,6 @@ package com.casic.dao.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.dao.model.DataTubeOther; import com.casic.dao.model.DeviceWellView; public interface IDeviceWellViewService extends IService { diff --git a/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java new file mode 100644 index 0000000..be34f77 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java @@ -0,0 +1,16 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.BusDeviceMapper; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import org.springframework.stereotype.Service; + +@Service +public class BusDeviceServiceImpl extends ServiceImpl implements IBusDeviceService { + + @Override + public BusDevice getDeviceByCode(String devCode) { + return baseMapper.getOneByDevCode(devCode); + } +} diff --git a/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java new file mode 100644 index 0000000..0db2007 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java @@ -0,0 +1,11 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.DataSentinelOtherMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.service.IDataSentinelOtherService; +import org.springframework.stereotype.Service; + +@Service +public class DataSentinelOtherServiceImpl extends ServiceImpl implements IDataSentinelOtherService { +} diff --git a/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java new file mode 100644 index 0000000..d8c5ef2 --- /dev/null +++ b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java @@ -0,0 +1,111 @@ +package com.casic.protocol; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.CasicProtocol; +import org.springframework.stereotype.Component; + +@Component +public class CasicTubeProtocolImpl implements CasicProtocol { + @Override + public boolean checkFrame(String frame) { + boolean valid = checkFrameHeaderAndTail(frame); + if (valid) { + valid = checkFrameLength(frame); + } + + return valid; + } + + private boolean checkFrameHeaderAndTail(String frame) { + return (frame.substring(0, 2).equalsIgnoreCase("AA")) && + (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); + } + + private boolean checkFrameLength(String frame) { + String lengthStr = frame.substring(4, 7); + int length = Integer.parseInt(lengthStr); + + return frame.length() == length + 9; + } + + @Override + public String getDeviceType(String frame) { + return frame.substring(7, 9); + } + + @Override + public String getDeviceId(String frame) { + return frame.substring(9, 21); + } + + @Override + public String getManufacturerCode(String frame) { + return frame.substring(11, 13); + } + + @Override + public String getMessageType(String frame) { + return frame.substring(21, 23); + } + + @Override + public String getMessageSequence(String frame) { + return frame.substring(23, 25); + } + + @Override + public String getMessageBody(String frame) { + return frame.substring(26, frame.length() - 16); + } + + @Override + public JSONObject parseMessageBody(String messageBody) { + return JSONObject.parseObject(messageBody); + } + + @Override + public String getUptime(String frame) { + return frame.substring(frame.length() - 16, frame.length() - 2); + } + + @Override + public String buildFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append(frame.getMessageBody().toJSONString()); + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } + + @Override + public String buildReplyFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append("00"); // 消息响应类消息 消息体为00 + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/senitnel/controller/SentinelDataController.java b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java new file mode 100644 index 0000000..633c072 --- /dev/null +++ b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java @@ -0,0 +1,120 @@ +package com.casic.senitnel.controller; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.general.ConfigFrame; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import com.casic.senitnel.service.ISentinelFrameService; +import com.casic.util.aep.AepCommandSend; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Base64; +import java.util.Map; + +@Slf4j +@RestController +public class SentinelDataController { + + @Resource + private ISentinelFrameService frameService; + + @Resource + private IBusDeviceService deviceService; + + @RequestMapping("/sentinel/data/recv") + public Object dataRecv(@RequestBody Map map) { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + + JSONObject recvObj = (JSONObject) JSONObject.toJSON(map); + if (recvObj.containsKey("payload")) { + JSONObject payload = recvObj.getJSONObject("payload"); + String value = payload.getString("APPdata"); + + if (value.isEmpty()) { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } else { + byte[] baseBytes = Base64.getDecoder().decode(value); + String frameStr = new String(baseBytes); + + // 根据协议进行解析 + CasicFrame frame = frameService.dataParse(frameStr); + + if (frame != null) { + // 回复响应 + String replyFrameStr = frameService.replyMessage(frame.getDeviceCode(), frame.getSequence()); + + // 从数据库中获取master-api-key 回复响应消息 + BusDevice device = deviceService.getDeviceByCode(frame.getDeviceCode()); + if (device != null && StringUtils.isNotBlank(device.getMasterApiKey())) { + String masterApiKey = device.getMasterApiKey(); + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + + try { + int code = aepCommandSend.handleAndReply(replyFrameStr); + } catch (Exception ex) { + log.error("向设备回复响应异常:{}", ex.getMessage()); + } + } + + // 存库 + frameService.afterAction(frame); + } + + retObj.put("code", 200); + retObj.put("success", true); + } + } else { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } + + return retObj; + } + + @RequestMapping("/sentinel/config/send") + public Object configSend(@RequestBody Map map) throws Exception { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + CasicFrame cmdFrame = new ConfigFrame(); + cmdFrame.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + cmdFrame.setDeviceCode((String) map.get("devCode")); + cmdFrame.setSequence("01"); + cmdFrame.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + JSONObject messageBody = new JSONObject(); + messageBody.put("datas", map.get("cmdList")); + cmdFrame.setMessageBody(messageBody); + + String frameStr = frameService.doBuildCommand(cmdFrame); + + // TODO-LIST + // 这三个参数根据设备编号从数据库中取 + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + String masterApiKey = (String) map.get("masterApiKey"); + + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + int code = aepCommandSend.handleAndReply(frameStr); + + retObj.put("code", 200); + retObj.put("success", true); + retObj.put("AEPRetCode", code); + return retObj; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java new file mode 100644 index 0000000..368af03 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java @@ -0,0 +1,82 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; +import com.casic.dao.model.DataMonitorPipeOther; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class DataFrameNCX extends DataFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + dataItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + DataItemNCX dataItem = new DataItemNCX(); + + dataItem.setLenL(dataObj.getString("LENGL")); + dataItem.setLenR(dataObj.getString("LENGR")); + dataItem.setBat(dataObj.getString("BAT")); + dataItem.setCh4L(dataObj.getString("CH4L")); + dataItem.setCh4R(dataObj.getString("CH4R")); + dataItem.setSlope(dataObj.getString("SLOPING")); + dataItem.setDestroy(dataObj.getString("DESTROY")); + dataItem.setLeak(dataObj.getString("LEAK")); + dataItem.setDiscL(dataObj.getString("DISCL")); + dataItem.setDiscR(dataObj.getString("DISCR")); + dataItem.setVibL(dataObj.getString("VIBL")); + dataItem.setVibR(dataObj.getString("VIBR")); + dataItem.setTime(dataObj.getString("UPTIME")); + + dataItemList.add(dataItem); + } + } + + @Override + public List toDataModelList() { + List dataList = new ArrayList<>(); + for (DataItem dataItem : dataItemList) { + DataMonitorPipeOther data = new DataMonitorPipeOther(); + + data.setDevcode(getDeviceCode()); + data.setLeftLength(((DataItemNCX)dataItem).getLenL()); + data.setRightLength(((DataItemNCX)dataItem).getLenR()); + data.setLeftGas(((DataItemNCX)dataItem).getCh4L()); + data.setRightGas(((DataItemNCX)dataItem).getCh4R()); + data.setVbat(((DataItemNCX)dataItem).getBat()); + data.setPipeInclineAlarm(((DataItemNCX)dataItem).getSlope()); + data.setPipeBreakAlarm(((DataItemNCX)dataItem).getDestroy()); + data.setGasAlarm(((DataItemNCX)dataItem).getLeak()); + data.setLeftOfflineAlarm(((DataItemNCX)dataItem).getDiscL()); + data.setRightOfflineAlarm(((DataItemNCX)dataItem).getDiscR()); + data.setLeftVibrateAlarm(((DataItemNCX)dataItem).getVibL()); + data.setRightVibrateAlarm(((DataItemNCX)dataItem).getVibR()); + data.setUptime(LocalDateTime.parse(((DataItemNCX)dataItem).getTime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 采集时间 + data.setLogtime(LocalDateTime.parse(getUptime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 上报时间 + + dataList.add(data); + } + + return dataList; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java new file mode 100644 index 0000000..372ac73 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java @@ -0,0 +1,31 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.DataItem; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class DataItemNCX extends DataItem { + String lenL; // 左侧指示带长度 + String lenR; // 右侧指示带长度 + String ch4L; // 左侧甲烷浓度值 + String ch4R; // 右侧甲烷浓度值 + String bat; // 电池电压 + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String spare; // 备用 + String time; // 采集时间 + + @Override + public String toString() { + return "气体浓度值:" + "(" + ch4L + "," + ch4R + ")" + "%LEL;" + + "电池电压值:" + bat + "v;" + + "采样时间:" + time; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java new file mode 100644 index 0000000..b3bbcf4 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java @@ -0,0 +1,43 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.EventFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class EventFrameNCX extends EventFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + eventItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + EventItemNCX eventItem = new EventItemNCX(); + + eventItem.setSlope(dataObj.getString("SLOPING")); + eventItem.setDestroy(dataObj.getString("DESTROY")); + eventItem.setLeak(dataObj.getString("LEAK")); + eventItem.setDiscL(dataObj.getString("DISCL")); + eventItem.setDiscR(dataObj.getString("DISCR")); + eventItem.setVibL(dataObj.getString("VIBL")); + eventItem.setVibR(dataObj.getString("VIBR")); + eventItem.setTime(dataObj.getString("UPTIME")); + + eventItemList.add(eventItem); + } + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java new file mode 100644 index 0000000..1a560d0 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java @@ -0,0 +1,49 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.EventItem; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.commons.lang3.StringUtils; + +@EqualsAndHashCode(callSuper = true) +@Data +public class EventItemNCX extends EventItem { + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String time; // 采集时间 + + @Override + public String toString() { + String str = ""; + if (StringUtils.isNotBlank(slope) && slope.equalsIgnoreCase("1")) { + str += "[倾斜报警]"; + } + if (StringUtils.isNotBlank(destroy) && destroy.equalsIgnoreCase("1")) { + str += "[破坏报警]"; + } + if (StringUtils.isNotBlank(leak) && leak.equalsIgnoreCase("1")) { + str += "[甲烷泄漏报警]"; + } + if (StringUtils.isNotBlank(discL) && discL.equalsIgnoreCase("1")) { + str += "[左侧断线报警]"; + } + if (StringUtils.isNotBlank(discR) && discR.equalsIgnoreCase("1")) { + str += "[右侧断线报警]"; + } + if (StringUtils.isNotBlank(vibL) && vibL.equalsIgnoreCase("1")) { + str += "[左侧振动报警]"; + } + if (StringUtils.isNotBlank(vibR) && vibR.equalsIgnoreCase("1")) { + str += "[右侧振动报警]"; + } + str += "采样时间:" + time; + + return str; + + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java new file mode 100644 index 0000000..343c4d6 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java @@ -0,0 +1,37 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class InfoFrameNCX extends CasicFrame { + + String workMode; + String model; + String hwVersion; + String softVersion; + String sensorType; + + @Override + public String toString() { + return "设备编号: " + getDeviceCode() + "; " + + "设备工作模式: " + workMode + " ; " + + "设备型号: " + model + " ; " + + "版本号: " + hwVersion + ", " + softVersion + "; " + + "传感器类型: " + sensorType + " ; " + + "上报时间: " + getUptime(); + } + + @Override + public void parseMessageBody() { + workMode = getMessageBody().getString("WORKMODE"); + model = getMessageBody().getString("MODEL"); + hwVersion = getMessageBody().getString("HWVERSION"); + softVersion = getMessageBody().getString("SOFTVERSION"); + sensorType = getMessageBody().getString("SENSORTYPE"); + } +} diff --git a/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java new file mode 100644 index 0000000..e76fc86 --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java @@ -0,0 +1,14 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; + +public interface ISentinelFrameService { + + CasicFrame dataParse(String frame); + + String replyMessage(String deviceCode, String sequence); + + String doBuildCommand(CasicFrame cmd); + + void afterAction(CasicFrame frame); +} diff --git a/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java new file mode 100644 index 0000000..803ff0e --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java @@ -0,0 +1,109 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; +import com.casic.common.CasicFrameBuildFactory; +import com.casic.common.CasicProtocol; +import com.casic.common.general.DataFrame; +import com.casic.common.general.EventFrame; +import com.casic.common.general.ReplyFrame; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.model.DeviceWellView; +import com.casic.dao.service.IDataSentinelOtherService; +import com.casic.dao.service.IDeviceWellViewService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + + +@Service +@Slf4j +public class SentinelFrameServiceImpl implements ISentinelFrameService { + + @Resource + private CasicProtocol protocol; + + @Resource + IDataSentinelOtherService sentinelDataService; + + @Resource + IDeviceWellViewService deviceService; + + public CasicFrame dataParse(String frame) { + // 1. 判断帧结构 + boolean frameValid = protocol.checkFrame(frame); + if (frameValid) { + // 2. 获取帧结构中的关键字段信息 + String deviceId = protocol.getDeviceId(frame); + String deviceType = protocol.getDeviceType(frame); + String messageType = protocol.getMessageType(frame); + String messageBody = protocol.getMessageBody(frame).toUpperCase(); + String uptime = protocol.getUptime(frame); + String sequence = protocol.getMessageSequence(frame); + + String manufacturerCode = protocol.getManufacturerCode(frame); + CasicFrame sentinelFrame = CasicFrameBuildFactory.buildCasicFrame(messageType, manufacturerCode, deviceType); + + if (sentinelFrame != null) { + sentinelFrame.setDeviceCode(deviceId); + sentinelFrame.setUptime(uptime); + sentinelFrame.setMessageType(messageType); + sentinelFrame.setSequence(sequence); + + // 心跳类的消息不解析MessageBody + if (!sentinelFrame.getMessageType().equals("00")) { + sentinelFrame.setMessageBody(protocol.parseMessageBody(messageBody)); + sentinelFrame.parseMessageBody(); + } + + log.info("收到设备消息:{}", sentinelFrame); + return sentinelFrame; + } + } else { + log.error("消息帧解析异常"); + } + + return null; + } + + @Override + public String replyMessage(String deviceCode, String sequence) { + CasicFrame reply = new ReplyFrame(); + reply.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + reply.setDeviceCode(deviceCode); + reply.setSequence(sequence); + reply.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + return protocol.buildReplyFrameStr(reply); + } + + @Override + public String doBuildCommand(CasicFrame cmd) { + return protocol.buildFrameStr(cmd); + } + + @Override + public void afterAction(CasicFrame frame) { + // 数据消息帧 进行存库操作 + if (frame instanceof DataFrame) { + String devCode = frame.getDeviceCode(); + DeviceWellView devWellView = deviceService.getDeviceWellViewByDevCode(devCode); + String wellCode = ""; + if (devWellView != null) { + wellCode = devWellView.getWellCode(); + } + List dataList = ((DataFrame) frame).toDataModelList(); + if (dataList != null) { + for (Serializable item : dataList) { + DataMonitorPipeOther data = (DataMonitorPipeOther) item; + data.setWellCode(wellCode); + sentinelDataService.save(data); + } + } + } + } +} diff --git a/src/main/java/com/casic/tube/controller/TubeDataController.java b/src/main/java/com/casic/tube/controller/TubeDataController.java index 61486c5..4965449 100644 --- a/src/main/java/com/casic/tube/controller/TubeDataController.java +++ b/src/main/java/com/casic/tube/controller/TubeDataController.java @@ -2,8 +2,8 @@ import com.alibaba.fastjson.JSONObject; import com.casic.common.CasicFrame; -import com.casic.tube.frame.ConfigFrame; -import com.casic.tube.service.ITubeDataService; +import com.casic.common.general.ConfigFrame; +import com.casic.tube.service.ITubeFrameService; import com.casic.util.aep.AepCommandSend; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestBody; @@ -21,7 +21,7 @@ public class TubeDataController { @Resource - private ITubeDataService tubeDataService; + private ITubeFrameService frameService; @RequestMapping("/tube/data/recv") public Object dataRecv(@RequestBody Map map) { @@ -42,10 +42,10 @@ String frameStr = new String(baseBytes); // 根据协议进行解析 - CasicFrame frame = tubeDataService.dataParse(frameStr); + CasicFrame frame = frameService.dataParse(frameStr); // 存库 - tubeDataService.afterAction(frame); + frameService.afterAction(frame); retObj.put("code", 200); retObj.put("success", true); @@ -74,7 +74,7 @@ messageBody.put("datas", map.get("cmdList")); cmdFrame.setMessageBody(messageBody); - String frameStr = tubeDataService.doBuildCommand(cmdFrame); + String frameStr = frameService.doBuildCommand(cmdFrame); // TODO-LIST // 这三个参数根据设备编号从数据库中取 diff --git a/src/main/java/com/casic/tube/frame/ConfigFrame.java b/src/main/java/com/casic/tube/frame/ConfigFrame.java deleted file mode 100644 index 883dad6..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigFrame.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigFrame extends CasicFrame { - - public ConfigFrame() { - setSequence("01"); // 默认序号 - setControl("1"); // 默认为不需要分包 - setMessageType("52"); // 消息大类 52 = SetRequest - } -} diff --git a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java b/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java deleted file mode 100644 index a419145..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigResponseFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "03"; - final String MESSAGE_TYPE_STRING = "SetResponse"; - final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "指令序号" + getSequence() + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/DataFrame.java b/src/main/java/com/casic/tube/frame/DataFrame.java deleted file mode 100644 index 97e07b8..0000000 --- a/src/main/java/com/casic/tube/frame/DataFrame.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import com.casic.dao.model.DataTubeOther; - -import java.util.List; - -public class DataFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "02"; - final String MESSAGE_TYPE_STRING = "Data/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "数据消息/管盯"; - - public List dataItemList; - - public List toDataModelList() { - return null; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append(";"); - builder.append("上报时间:").append(getUptime()).append(";"); - for (DataItem dataItem : dataItemList) { - builder.append("["); - builder.append(dataItem); - builder.append("],"); - } - builder.deleteCharAt(builder.length() - 1); - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/DataItem.java b/src/main/java/com/casic/tube/frame/DataItem.java deleted file mode 100644 index 4e9aceb..0000000 --- a/src/main/java/com/casic/tube/frame/DataItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class DataItem { -} diff --git a/src/main/java/com/casic/tube/frame/EventFrame.java b/src/main/java/com/casic/tube/frame/EventFrame.java deleted file mode 100644 index ea800b4..0000000 --- a/src/main/java/com/casic/tube/frame/EventFrame.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -import java.util.List; - -public class EventFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "01"; - final String MESSAGE_TYPE_STRING = "Event/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "事件消息/管盯"; - - public List eventItemList; - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append("; "); - builder.append("上报时间:").append(getUptime()).append("; "); - for (EventItem eventItem : eventItemList) { - builder.append("["); - builder.append(eventItem); - builder.append("],"); - } - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/EventItem.java b/src/main/java/com/casic/tube/frame/EventItem.java deleted file mode 100644 index a1245bf..0000000 --- a/src/main/java/com/casic/tube/frame/EventItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class EventItem { -} diff --git a/src/main/java/com/casic/tube/frame/HeartFrame.java b/src/main/java/com/casic/tube/frame/HeartFrame.java deleted file mode 100644 index af7e7a6..0000000 --- a/src/main/java/com/casic/tube/frame/HeartFrame.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; - -@Data -public class HeartFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "00"; - final String MESSAGE_TYPE_STRING = "OnlineRequest"; - final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/IMEIFrame.java b/src/main/java/com/casic/tube/frame/IMEIFrame.java deleted file mode 100644 index 9420620..0000000 --- a/src/main/java/com/casic/tube/frame/IMEIFrame.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; - -@Data -public class IMEIFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "05"; - final String MESSAGE_TYPE_STRING = "StartupRequest"; - final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; - - String imei; - String iccid; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "IMEI:" + imei + ";" + - "ICCID:" + iccid + - "}"; - } - - @Override - public void parseMessageBody() { - imei = getMessageBody().getString("IMEI"); - iccid = getMessageBody().getString("ICCID"); - } -} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java new file mode 100644 index 0000000..95d2bd4 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java @@ -0,0 +1,8 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.DataMonitorPipeOther; + +public interface IDataSentinelOtherService extends IService { + +} diff --git a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java index d6b1200..0290829 100644 --- a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java +++ b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java @@ -1,7 +1,6 @@ package com.casic.dao.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.dao.model.DataTubeOther; import com.casic.dao.model.DeviceWellView; public interface IDeviceWellViewService extends IService { diff --git a/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java new file mode 100644 index 0000000..be34f77 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java @@ -0,0 +1,16 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.BusDeviceMapper; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import org.springframework.stereotype.Service; + +@Service +public class BusDeviceServiceImpl extends ServiceImpl implements IBusDeviceService { + + @Override + public BusDevice getDeviceByCode(String devCode) { + return baseMapper.getOneByDevCode(devCode); + } +} diff --git a/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java new file mode 100644 index 0000000..0db2007 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java @@ -0,0 +1,11 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.DataSentinelOtherMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.service.IDataSentinelOtherService; +import org.springframework.stereotype.Service; + +@Service +public class DataSentinelOtherServiceImpl extends ServiceImpl implements IDataSentinelOtherService { +} diff --git a/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java new file mode 100644 index 0000000..d8c5ef2 --- /dev/null +++ b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java @@ -0,0 +1,111 @@ +package com.casic.protocol; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.CasicProtocol; +import org.springframework.stereotype.Component; + +@Component +public class CasicTubeProtocolImpl implements CasicProtocol { + @Override + public boolean checkFrame(String frame) { + boolean valid = checkFrameHeaderAndTail(frame); + if (valid) { + valid = checkFrameLength(frame); + } + + return valid; + } + + private boolean checkFrameHeaderAndTail(String frame) { + return (frame.substring(0, 2).equalsIgnoreCase("AA")) && + (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); + } + + private boolean checkFrameLength(String frame) { + String lengthStr = frame.substring(4, 7); + int length = Integer.parseInt(lengthStr); + + return frame.length() == length + 9; + } + + @Override + public String getDeviceType(String frame) { + return frame.substring(7, 9); + } + + @Override + public String getDeviceId(String frame) { + return frame.substring(9, 21); + } + + @Override + public String getManufacturerCode(String frame) { + return frame.substring(11, 13); + } + + @Override + public String getMessageType(String frame) { + return frame.substring(21, 23); + } + + @Override + public String getMessageSequence(String frame) { + return frame.substring(23, 25); + } + + @Override + public String getMessageBody(String frame) { + return frame.substring(26, frame.length() - 16); + } + + @Override + public JSONObject parseMessageBody(String messageBody) { + return JSONObject.parseObject(messageBody); + } + + @Override + public String getUptime(String frame) { + return frame.substring(frame.length() - 16, frame.length() - 2); + } + + @Override + public String buildFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append(frame.getMessageBody().toJSONString()); + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } + + @Override + public String buildReplyFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append("00"); // 消息响应类消息 消息体为00 + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/senitnel/controller/SentinelDataController.java b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java new file mode 100644 index 0000000..633c072 --- /dev/null +++ b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java @@ -0,0 +1,120 @@ +package com.casic.senitnel.controller; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.general.ConfigFrame; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import com.casic.senitnel.service.ISentinelFrameService; +import com.casic.util.aep.AepCommandSend; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Base64; +import java.util.Map; + +@Slf4j +@RestController +public class SentinelDataController { + + @Resource + private ISentinelFrameService frameService; + + @Resource + private IBusDeviceService deviceService; + + @RequestMapping("/sentinel/data/recv") + public Object dataRecv(@RequestBody Map map) { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + + JSONObject recvObj = (JSONObject) JSONObject.toJSON(map); + if (recvObj.containsKey("payload")) { + JSONObject payload = recvObj.getJSONObject("payload"); + String value = payload.getString("APPdata"); + + if (value.isEmpty()) { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } else { + byte[] baseBytes = Base64.getDecoder().decode(value); + String frameStr = new String(baseBytes); + + // 根据协议进行解析 + CasicFrame frame = frameService.dataParse(frameStr); + + if (frame != null) { + // 回复响应 + String replyFrameStr = frameService.replyMessage(frame.getDeviceCode(), frame.getSequence()); + + // 从数据库中获取master-api-key 回复响应消息 + BusDevice device = deviceService.getDeviceByCode(frame.getDeviceCode()); + if (device != null && StringUtils.isNotBlank(device.getMasterApiKey())) { + String masterApiKey = device.getMasterApiKey(); + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + + try { + int code = aepCommandSend.handleAndReply(replyFrameStr); + } catch (Exception ex) { + log.error("向设备回复响应异常:{}", ex.getMessage()); + } + } + + // 存库 + frameService.afterAction(frame); + } + + retObj.put("code", 200); + retObj.put("success", true); + } + } else { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } + + return retObj; + } + + @RequestMapping("/sentinel/config/send") + public Object configSend(@RequestBody Map map) throws Exception { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + CasicFrame cmdFrame = new ConfigFrame(); + cmdFrame.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + cmdFrame.setDeviceCode((String) map.get("devCode")); + cmdFrame.setSequence("01"); + cmdFrame.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + JSONObject messageBody = new JSONObject(); + messageBody.put("datas", map.get("cmdList")); + cmdFrame.setMessageBody(messageBody); + + String frameStr = frameService.doBuildCommand(cmdFrame); + + // TODO-LIST + // 这三个参数根据设备编号从数据库中取 + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + String masterApiKey = (String) map.get("masterApiKey"); + + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + int code = aepCommandSend.handleAndReply(frameStr); + + retObj.put("code", 200); + retObj.put("success", true); + retObj.put("AEPRetCode", code); + return retObj; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java new file mode 100644 index 0000000..368af03 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java @@ -0,0 +1,82 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; +import com.casic.dao.model.DataMonitorPipeOther; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class DataFrameNCX extends DataFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + dataItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + DataItemNCX dataItem = new DataItemNCX(); + + dataItem.setLenL(dataObj.getString("LENGL")); + dataItem.setLenR(dataObj.getString("LENGR")); + dataItem.setBat(dataObj.getString("BAT")); + dataItem.setCh4L(dataObj.getString("CH4L")); + dataItem.setCh4R(dataObj.getString("CH4R")); + dataItem.setSlope(dataObj.getString("SLOPING")); + dataItem.setDestroy(dataObj.getString("DESTROY")); + dataItem.setLeak(dataObj.getString("LEAK")); + dataItem.setDiscL(dataObj.getString("DISCL")); + dataItem.setDiscR(dataObj.getString("DISCR")); + dataItem.setVibL(dataObj.getString("VIBL")); + dataItem.setVibR(dataObj.getString("VIBR")); + dataItem.setTime(dataObj.getString("UPTIME")); + + dataItemList.add(dataItem); + } + } + + @Override + public List toDataModelList() { + List dataList = new ArrayList<>(); + for (DataItem dataItem : dataItemList) { + DataMonitorPipeOther data = new DataMonitorPipeOther(); + + data.setDevcode(getDeviceCode()); + data.setLeftLength(((DataItemNCX)dataItem).getLenL()); + data.setRightLength(((DataItemNCX)dataItem).getLenR()); + data.setLeftGas(((DataItemNCX)dataItem).getCh4L()); + data.setRightGas(((DataItemNCX)dataItem).getCh4R()); + data.setVbat(((DataItemNCX)dataItem).getBat()); + data.setPipeInclineAlarm(((DataItemNCX)dataItem).getSlope()); + data.setPipeBreakAlarm(((DataItemNCX)dataItem).getDestroy()); + data.setGasAlarm(((DataItemNCX)dataItem).getLeak()); + data.setLeftOfflineAlarm(((DataItemNCX)dataItem).getDiscL()); + data.setRightOfflineAlarm(((DataItemNCX)dataItem).getDiscR()); + data.setLeftVibrateAlarm(((DataItemNCX)dataItem).getVibL()); + data.setRightVibrateAlarm(((DataItemNCX)dataItem).getVibR()); + data.setUptime(LocalDateTime.parse(((DataItemNCX)dataItem).getTime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 采集时间 + data.setLogtime(LocalDateTime.parse(getUptime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 上报时间 + + dataList.add(data); + } + + return dataList; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java new file mode 100644 index 0000000..372ac73 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java @@ -0,0 +1,31 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.DataItem; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class DataItemNCX extends DataItem { + String lenL; // 左侧指示带长度 + String lenR; // 右侧指示带长度 + String ch4L; // 左侧甲烷浓度值 + String ch4R; // 右侧甲烷浓度值 + String bat; // 电池电压 + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String spare; // 备用 + String time; // 采集时间 + + @Override + public String toString() { + return "气体浓度值:" + "(" + ch4L + "," + ch4R + ")" + "%LEL;" + + "电池电压值:" + bat + "v;" + + "采样时间:" + time; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java new file mode 100644 index 0000000..b3bbcf4 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java @@ -0,0 +1,43 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.EventFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class EventFrameNCX extends EventFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + eventItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + EventItemNCX eventItem = new EventItemNCX(); + + eventItem.setSlope(dataObj.getString("SLOPING")); + eventItem.setDestroy(dataObj.getString("DESTROY")); + eventItem.setLeak(dataObj.getString("LEAK")); + eventItem.setDiscL(dataObj.getString("DISCL")); + eventItem.setDiscR(dataObj.getString("DISCR")); + eventItem.setVibL(dataObj.getString("VIBL")); + eventItem.setVibR(dataObj.getString("VIBR")); + eventItem.setTime(dataObj.getString("UPTIME")); + + eventItemList.add(eventItem); + } + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java new file mode 100644 index 0000000..1a560d0 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java @@ -0,0 +1,49 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.EventItem; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.commons.lang3.StringUtils; + +@EqualsAndHashCode(callSuper = true) +@Data +public class EventItemNCX extends EventItem { + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String time; // 采集时间 + + @Override + public String toString() { + String str = ""; + if (StringUtils.isNotBlank(slope) && slope.equalsIgnoreCase("1")) { + str += "[倾斜报警]"; + } + if (StringUtils.isNotBlank(destroy) && destroy.equalsIgnoreCase("1")) { + str += "[破坏报警]"; + } + if (StringUtils.isNotBlank(leak) && leak.equalsIgnoreCase("1")) { + str += "[甲烷泄漏报警]"; + } + if (StringUtils.isNotBlank(discL) && discL.equalsIgnoreCase("1")) { + str += "[左侧断线报警]"; + } + if (StringUtils.isNotBlank(discR) && discR.equalsIgnoreCase("1")) { + str += "[右侧断线报警]"; + } + if (StringUtils.isNotBlank(vibL) && vibL.equalsIgnoreCase("1")) { + str += "[左侧振动报警]"; + } + if (StringUtils.isNotBlank(vibR) && vibR.equalsIgnoreCase("1")) { + str += "[右侧振动报警]"; + } + str += "采样时间:" + time; + + return str; + + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java new file mode 100644 index 0000000..343c4d6 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java @@ -0,0 +1,37 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class InfoFrameNCX extends CasicFrame { + + String workMode; + String model; + String hwVersion; + String softVersion; + String sensorType; + + @Override + public String toString() { + return "设备编号: " + getDeviceCode() + "; " + + "设备工作模式: " + workMode + " ; " + + "设备型号: " + model + " ; " + + "版本号: " + hwVersion + ", " + softVersion + "; " + + "传感器类型: " + sensorType + " ; " + + "上报时间: " + getUptime(); + } + + @Override + public void parseMessageBody() { + workMode = getMessageBody().getString("WORKMODE"); + model = getMessageBody().getString("MODEL"); + hwVersion = getMessageBody().getString("HWVERSION"); + softVersion = getMessageBody().getString("SOFTVERSION"); + sensorType = getMessageBody().getString("SENSORTYPE"); + } +} diff --git a/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java new file mode 100644 index 0000000..e76fc86 --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java @@ -0,0 +1,14 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; + +public interface ISentinelFrameService { + + CasicFrame dataParse(String frame); + + String replyMessage(String deviceCode, String sequence); + + String doBuildCommand(CasicFrame cmd); + + void afterAction(CasicFrame frame); +} diff --git a/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java new file mode 100644 index 0000000..803ff0e --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java @@ -0,0 +1,109 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; +import com.casic.common.CasicFrameBuildFactory; +import com.casic.common.CasicProtocol; +import com.casic.common.general.DataFrame; +import com.casic.common.general.EventFrame; +import com.casic.common.general.ReplyFrame; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.model.DeviceWellView; +import com.casic.dao.service.IDataSentinelOtherService; +import com.casic.dao.service.IDeviceWellViewService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + + +@Service +@Slf4j +public class SentinelFrameServiceImpl implements ISentinelFrameService { + + @Resource + private CasicProtocol protocol; + + @Resource + IDataSentinelOtherService sentinelDataService; + + @Resource + IDeviceWellViewService deviceService; + + public CasicFrame dataParse(String frame) { + // 1. 判断帧结构 + boolean frameValid = protocol.checkFrame(frame); + if (frameValid) { + // 2. 获取帧结构中的关键字段信息 + String deviceId = protocol.getDeviceId(frame); + String deviceType = protocol.getDeviceType(frame); + String messageType = protocol.getMessageType(frame); + String messageBody = protocol.getMessageBody(frame).toUpperCase(); + String uptime = protocol.getUptime(frame); + String sequence = protocol.getMessageSequence(frame); + + String manufacturerCode = protocol.getManufacturerCode(frame); + CasicFrame sentinelFrame = CasicFrameBuildFactory.buildCasicFrame(messageType, manufacturerCode, deviceType); + + if (sentinelFrame != null) { + sentinelFrame.setDeviceCode(deviceId); + sentinelFrame.setUptime(uptime); + sentinelFrame.setMessageType(messageType); + sentinelFrame.setSequence(sequence); + + // 心跳类的消息不解析MessageBody + if (!sentinelFrame.getMessageType().equals("00")) { + sentinelFrame.setMessageBody(protocol.parseMessageBody(messageBody)); + sentinelFrame.parseMessageBody(); + } + + log.info("收到设备消息:{}", sentinelFrame); + return sentinelFrame; + } + } else { + log.error("消息帧解析异常"); + } + + return null; + } + + @Override + public String replyMessage(String deviceCode, String sequence) { + CasicFrame reply = new ReplyFrame(); + reply.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + reply.setDeviceCode(deviceCode); + reply.setSequence(sequence); + reply.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + return protocol.buildReplyFrameStr(reply); + } + + @Override + public String doBuildCommand(CasicFrame cmd) { + return protocol.buildFrameStr(cmd); + } + + @Override + public void afterAction(CasicFrame frame) { + // 数据消息帧 进行存库操作 + if (frame instanceof DataFrame) { + String devCode = frame.getDeviceCode(); + DeviceWellView devWellView = deviceService.getDeviceWellViewByDevCode(devCode); + String wellCode = ""; + if (devWellView != null) { + wellCode = devWellView.getWellCode(); + } + List dataList = ((DataFrame) frame).toDataModelList(); + if (dataList != null) { + for (Serializable item : dataList) { + DataMonitorPipeOther data = (DataMonitorPipeOther) item; + data.setWellCode(wellCode); + sentinelDataService.save(data); + } + } + } + } +} diff --git a/src/main/java/com/casic/tube/controller/TubeDataController.java b/src/main/java/com/casic/tube/controller/TubeDataController.java index 61486c5..4965449 100644 --- a/src/main/java/com/casic/tube/controller/TubeDataController.java +++ b/src/main/java/com/casic/tube/controller/TubeDataController.java @@ -2,8 +2,8 @@ import com.alibaba.fastjson.JSONObject; import com.casic.common.CasicFrame; -import com.casic.tube.frame.ConfigFrame; -import com.casic.tube.service.ITubeDataService; +import com.casic.common.general.ConfigFrame; +import com.casic.tube.service.ITubeFrameService; import com.casic.util.aep.AepCommandSend; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestBody; @@ -21,7 +21,7 @@ public class TubeDataController { @Resource - private ITubeDataService tubeDataService; + private ITubeFrameService frameService; @RequestMapping("/tube/data/recv") public Object dataRecv(@RequestBody Map map) { @@ -42,10 +42,10 @@ String frameStr = new String(baseBytes); // 根据协议进行解析 - CasicFrame frame = tubeDataService.dataParse(frameStr); + CasicFrame frame = frameService.dataParse(frameStr); // 存库 - tubeDataService.afterAction(frame); + frameService.afterAction(frame); retObj.put("code", 200); retObj.put("success", true); @@ -74,7 +74,7 @@ messageBody.put("datas", map.get("cmdList")); cmdFrame.setMessageBody(messageBody); - String frameStr = tubeDataService.doBuildCommand(cmdFrame); + String frameStr = frameService.doBuildCommand(cmdFrame); // TODO-LIST // 这三个参数根据设备编号从数据库中取 diff --git a/src/main/java/com/casic/tube/frame/ConfigFrame.java b/src/main/java/com/casic/tube/frame/ConfigFrame.java deleted file mode 100644 index 883dad6..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigFrame.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigFrame extends CasicFrame { - - public ConfigFrame() { - setSequence("01"); // 默认序号 - setControl("1"); // 默认为不需要分包 - setMessageType("52"); // 消息大类 52 = SetRequest - } -} diff --git a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java b/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java deleted file mode 100644 index a419145..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigResponseFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "03"; - final String MESSAGE_TYPE_STRING = "SetResponse"; - final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "指令序号" + getSequence() + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/DataFrame.java b/src/main/java/com/casic/tube/frame/DataFrame.java deleted file mode 100644 index 97e07b8..0000000 --- a/src/main/java/com/casic/tube/frame/DataFrame.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import com.casic.dao.model.DataTubeOther; - -import java.util.List; - -public class DataFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "02"; - final String MESSAGE_TYPE_STRING = "Data/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "数据消息/管盯"; - - public List dataItemList; - - public List toDataModelList() { - return null; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append(";"); - builder.append("上报时间:").append(getUptime()).append(";"); - for (DataItem dataItem : dataItemList) { - builder.append("["); - builder.append(dataItem); - builder.append("],"); - } - builder.deleteCharAt(builder.length() - 1); - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/DataItem.java b/src/main/java/com/casic/tube/frame/DataItem.java deleted file mode 100644 index 4e9aceb..0000000 --- a/src/main/java/com/casic/tube/frame/DataItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class DataItem { -} diff --git a/src/main/java/com/casic/tube/frame/EventFrame.java b/src/main/java/com/casic/tube/frame/EventFrame.java deleted file mode 100644 index ea800b4..0000000 --- a/src/main/java/com/casic/tube/frame/EventFrame.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -import java.util.List; - -public class EventFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "01"; - final String MESSAGE_TYPE_STRING = "Event/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "事件消息/管盯"; - - public List eventItemList; - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append("; "); - builder.append("上报时间:").append(getUptime()).append("; "); - for (EventItem eventItem : eventItemList) { - builder.append("["); - builder.append(eventItem); - builder.append("],"); - } - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/EventItem.java b/src/main/java/com/casic/tube/frame/EventItem.java deleted file mode 100644 index a1245bf..0000000 --- a/src/main/java/com/casic/tube/frame/EventItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class EventItem { -} diff --git a/src/main/java/com/casic/tube/frame/HeartFrame.java b/src/main/java/com/casic/tube/frame/HeartFrame.java deleted file mode 100644 index af7e7a6..0000000 --- a/src/main/java/com/casic/tube/frame/HeartFrame.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; - -@Data -public class HeartFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "00"; - final String MESSAGE_TYPE_STRING = "OnlineRequest"; - final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/IMEIFrame.java b/src/main/java/com/casic/tube/frame/IMEIFrame.java deleted file mode 100644 index 9420620..0000000 --- a/src/main/java/com/casic/tube/frame/IMEIFrame.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; - -@Data -public class IMEIFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "05"; - final String MESSAGE_TYPE_STRING = "StartupRequest"; - final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; - - String imei; - String iccid; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "IMEI:" + imei + ";" + - "ICCID:" + iccid + - "}"; - } - - @Override - public void parseMessageBody() { - imei = getMessageBody().getString("IMEI"); - iccid = getMessageBody().getString("ICCID"); - } -} diff --git a/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java b/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java index 50e8a2b..47bf4d6 100644 --- a/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java @@ -3,11 +3,12 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.casic.dao.model.DataTubeOther; -import com.casic.tube.frame.DataFrame; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -19,7 +20,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override @@ -43,8 +45,8 @@ } @Override - public List toDataModelList() { - List dataList = new ArrayList<>(); + public List toDataModelList() { + List dataList = new ArrayList<>(); for (DataItem dataItem : dataItemList) { DataTubeOther data = new DataTubeOther(); diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java new file mode 100644 index 0000000..95d2bd4 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java @@ -0,0 +1,8 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.DataMonitorPipeOther; + +public interface IDataSentinelOtherService extends IService { + +} diff --git a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java index d6b1200..0290829 100644 --- a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java +++ b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java @@ -1,7 +1,6 @@ package com.casic.dao.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.dao.model.DataTubeOther; import com.casic.dao.model.DeviceWellView; public interface IDeviceWellViewService extends IService { diff --git a/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java new file mode 100644 index 0000000..be34f77 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java @@ -0,0 +1,16 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.BusDeviceMapper; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import org.springframework.stereotype.Service; + +@Service +public class BusDeviceServiceImpl extends ServiceImpl implements IBusDeviceService { + + @Override + public BusDevice getDeviceByCode(String devCode) { + return baseMapper.getOneByDevCode(devCode); + } +} diff --git a/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java new file mode 100644 index 0000000..0db2007 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java @@ -0,0 +1,11 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.DataSentinelOtherMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.service.IDataSentinelOtherService; +import org.springframework.stereotype.Service; + +@Service +public class DataSentinelOtherServiceImpl extends ServiceImpl implements IDataSentinelOtherService { +} diff --git a/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java new file mode 100644 index 0000000..d8c5ef2 --- /dev/null +++ b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java @@ -0,0 +1,111 @@ +package com.casic.protocol; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.CasicProtocol; +import org.springframework.stereotype.Component; + +@Component +public class CasicTubeProtocolImpl implements CasicProtocol { + @Override + public boolean checkFrame(String frame) { + boolean valid = checkFrameHeaderAndTail(frame); + if (valid) { + valid = checkFrameLength(frame); + } + + return valid; + } + + private boolean checkFrameHeaderAndTail(String frame) { + return (frame.substring(0, 2).equalsIgnoreCase("AA")) && + (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); + } + + private boolean checkFrameLength(String frame) { + String lengthStr = frame.substring(4, 7); + int length = Integer.parseInt(lengthStr); + + return frame.length() == length + 9; + } + + @Override + public String getDeviceType(String frame) { + return frame.substring(7, 9); + } + + @Override + public String getDeviceId(String frame) { + return frame.substring(9, 21); + } + + @Override + public String getManufacturerCode(String frame) { + return frame.substring(11, 13); + } + + @Override + public String getMessageType(String frame) { + return frame.substring(21, 23); + } + + @Override + public String getMessageSequence(String frame) { + return frame.substring(23, 25); + } + + @Override + public String getMessageBody(String frame) { + return frame.substring(26, frame.length() - 16); + } + + @Override + public JSONObject parseMessageBody(String messageBody) { + return JSONObject.parseObject(messageBody); + } + + @Override + public String getUptime(String frame) { + return frame.substring(frame.length() - 16, frame.length() - 2); + } + + @Override + public String buildFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append(frame.getMessageBody().toJSONString()); + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } + + @Override + public String buildReplyFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append("00"); // 消息响应类消息 消息体为00 + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/senitnel/controller/SentinelDataController.java b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java new file mode 100644 index 0000000..633c072 --- /dev/null +++ b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java @@ -0,0 +1,120 @@ +package com.casic.senitnel.controller; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.general.ConfigFrame; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import com.casic.senitnel.service.ISentinelFrameService; +import com.casic.util.aep.AepCommandSend; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Base64; +import java.util.Map; + +@Slf4j +@RestController +public class SentinelDataController { + + @Resource + private ISentinelFrameService frameService; + + @Resource + private IBusDeviceService deviceService; + + @RequestMapping("/sentinel/data/recv") + public Object dataRecv(@RequestBody Map map) { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + + JSONObject recvObj = (JSONObject) JSONObject.toJSON(map); + if (recvObj.containsKey("payload")) { + JSONObject payload = recvObj.getJSONObject("payload"); + String value = payload.getString("APPdata"); + + if (value.isEmpty()) { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } else { + byte[] baseBytes = Base64.getDecoder().decode(value); + String frameStr = new String(baseBytes); + + // 根据协议进行解析 + CasicFrame frame = frameService.dataParse(frameStr); + + if (frame != null) { + // 回复响应 + String replyFrameStr = frameService.replyMessage(frame.getDeviceCode(), frame.getSequence()); + + // 从数据库中获取master-api-key 回复响应消息 + BusDevice device = deviceService.getDeviceByCode(frame.getDeviceCode()); + if (device != null && StringUtils.isNotBlank(device.getMasterApiKey())) { + String masterApiKey = device.getMasterApiKey(); + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + + try { + int code = aepCommandSend.handleAndReply(replyFrameStr); + } catch (Exception ex) { + log.error("向设备回复响应异常:{}", ex.getMessage()); + } + } + + // 存库 + frameService.afterAction(frame); + } + + retObj.put("code", 200); + retObj.put("success", true); + } + } else { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } + + return retObj; + } + + @RequestMapping("/sentinel/config/send") + public Object configSend(@RequestBody Map map) throws Exception { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + CasicFrame cmdFrame = new ConfigFrame(); + cmdFrame.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + cmdFrame.setDeviceCode((String) map.get("devCode")); + cmdFrame.setSequence("01"); + cmdFrame.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + JSONObject messageBody = new JSONObject(); + messageBody.put("datas", map.get("cmdList")); + cmdFrame.setMessageBody(messageBody); + + String frameStr = frameService.doBuildCommand(cmdFrame); + + // TODO-LIST + // 这三个参数根据设备编号从数据库中取 + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + String masterApiKey = (String) map.get("masterApiKey"); + + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + int code = aepCommandSend.handleAndReply(frameStr); + + retObj.put("code", 200); + retObj.put("success", true); + retObj.put("AEPRetCode", code); + return retObj; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java new file mode 100644 index 0000000..368af03 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java @@ -0,0 +1,82 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; +import com.casic.dao.model.DataMonitorPipeOther; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class DataFrameNCX extends DataFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + dataItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + DataItemNCX dataItem = new DataItemNCX(); + + dataItem.setLenL(dataObj.getString("LENGL")); + dataItem.setLenR(dataObj.getString("LENGR")); + dataItem.setBat(dataObj.getString("BAT")); + dataItem.setCh4L(dataObj.getString("CH4L")); + dataItem.setCh4R(dataObj.getString("CH4R")); + dataItem.setSlope(dataObj.getString("SLOPING")); + dataItem.setDestroy(dataObj.getString("DESTROY")); + dataItem.setLeak(dataObj.getString("LEAK")); + dataItem.setDiscL(dataObj.getString("DISCL")); + dataItem.setDiscR(dataObj.getString("DISCR")); + dataItem.setVibL(dataObj.getString("VIBL")); + dataItem.setVibR(dataObj.getString("VIBR")); + dataItem.setTime(dataObj.getString("UPTIME")); + + dataItemList.add(dataItem); + } + } + + @Override + public List toDataModelList() { + List dataList = new ArrayList<>(); + for (DataItem dataItem : dataItemList) { + DataMonitorPipeOther data = new DataMonitorPipeOther(); + + data.setDevcode(getDeviceCode()); + data.setLeftLength(((DataItemNCX)dataItem).getLenL()); + data.setRightLength(((DataItemNCX)dataItem).getLenR()); + data.setLeftGas(((DataItemNCX)dataItem).getCh4L()); + data.setRightGas(((DataItemNCX)dataItem).getCh4R()); + data.setVbat(((DataItemNCX)dataItem).getBat()); + data.setPipeInclineAlarm(((DataItemNCX)dataItem).getSlope()); + data.setPipeBreakAlarm(((DataItemNCX)dataItem).getDestroy()); + data.setGasAlarm(((DataItemNCX)dataItem).getLeak()); + data.setLeftOfflineAlarm(((DataItemNCX)dataItem).getDiscL()); + data.setRightOfflineAlarm(((DataItemNCX)dataItem).getDiscR()); + data.setLeftVibrateAlarm(((DataItemNCX)dataItem).getVibL()); + data.setRightVibrateAlarm(((DataItemNCX)dataItem).getVibR()); + data.setUptime(LocalDateTime.parse(((DataItemNCX)dataItem).getTime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 采集时间 + data.setLogtime(LocalDateTime.parse(getUptime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 上报时间 + + dataList.add(data); + } + + return dataList; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java new file mode 100644 index 0000000..372ac73 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java @@ -0,0 +1,31 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.DataItem; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class DataItemNCX extends DataItem { + String lenL; // 左侧指示带长度 + String lenR; // 右侧指示带长度 + String ch4L; // 左侧甲烷浓度值 + String ch4R; // 右侧甲烷浓度值 + String bat; // 电池电压 + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String spare; // 备用 + String time; // 采集时间 + + @Override + public String toString() { + return "气体浓度值:" + "(" + ch4L + "," + ch4R + ")" + "%LEL;" + + "电池电压值:" + bat + "v;" + + "采样时间:" + time; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java new file mode 100644 index 0000000..b3bbcf4 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java @@ -0,0 +1,43 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.EventFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class EventFrameNCX extends EventFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + eventItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + EventItemNCX eventItem = new EventItemNCX(); + + eventItem.setSlope(dataObj.getString("SLOPING")); + eventItem.setDestroy(dataObj.getString("DESTROY")); + eventItem.setLeak(dataObj.getString("LEAK")); + eventItem.setDiscL(dataObj.getString("DISCL")); + eventItem.setDiscR(dataObj.getString("DISCR")); + eventItem.setVibL(dataObj.getString("VIBL")); + eventItem.setVibR(dataObj.getString("VIBR")); + eventItem.setTime(dataObj.getString("UPTIME")); + + eventItemList.add(eventItem); + } + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java new file mode 100644 index 0000000..1a560d0 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java @@ -0,0 +1,49 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.EventItem; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.commons.lang3.StringUtils; + +@EqualsAndHashCode(callSuper = true) +@Data +public class EventItemNCX extends EventItem { + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String time; // 采集时间 + + @Override + public String toString() { + String str = ""; + if (StringUtils.isNotBlank(slope) && slope.equalsIgnoreCase("1")) { + str += "[倾斜报警]"; + } + if (StringUtils.isNotBlank(destroy) && destroy.equalsIgnoreCase("1")) { + str += "[破坏报警]"; + } + if (StringUtils.isNotBlank(leak) && leak.equalsIgnoreCase("1")) { + str += "[甲烷泄漏报警]"; + } + if (StringUtils.isNotBlank(discL) && discL.equalsIgnoreCase("1")) { + str += "[左侧断线报警]"; + } + if (StringUtils.isNotBlank(discR) && discR.equalsIgnoreCase("1")) { + str += "[右侧断线报警]"; + } + if (StringUtils.isNotBlank(vibL) && vibL.equalsIgnoreCase("1")) { + str += "[左侧振动报警]"; + } + if (StringUtils.isNotBlank(vibR) && vibR.equalsIgnoreCase("1")) { + str += "[右侧振动报警]"; + } + str += "采样时间:" + time; + + return str; + + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java new file mode 100644 index 0000000..343c4d6 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java @@ -0,0 +1,37 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class InfoFrameNCX extends CasicFrame { + + String workMode; + String model; + String hwVersion; + String softVersion; + String sensorType; + + @Override + public String toString() { + return "设备编号: " + getDeviceCode() + "; " + + "设备工作模式: " + workMode + " ; " + + "设备型号: " + model + " ; " + + "版本号: " + hwVersion + ", " + softVersion + "; " + + "传感器类型: " + sensorType + " ; " + + "上报时间: " + getUptime(); + } + + @Override + public void parseMessageBody() { + workMode = getMessageBody().getString("WORKMODE"); + model = getMessageBody().getString("MODEL"); + hwVersion = getMessageBody().getString("HWVERSION"); + softVersion = getMessageBody().getString("SOFTVERSION"); + sensorType = getMessageBody().getString("SENSORTYPE"); + } +} diff --git a/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java new file mode 100644 index 0000000..e76fc86 --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java @@ -0,0 +1,14 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; + +public interface ISentinelFrameService { + + CasicFrame dataParse(String frame); + + String replyMessage(String deviceCode, String sequence); + + String doBuildCommand(CasicFrame cmd); + + void afterAction(CasicFrame frame); +} diff --git a/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java new file mode 100644 index 0000000..803ff0e --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java @@ -0,0 +1,109 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; +import com.casic.common.CasicFrameBuildFactory; +import com.casic.common.CasicProtocol; +import com.casic.common.general.DataFrame; +import com.casic.common.general.EventFrame; +import com.casic.common.general.ReplyFrame; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.model.DeviceWellView; +import com.casic.dao.service.IDataSentinelOtherService; +import com.casic.dao.service.IDeviceWellViewService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + + +@Service +@Slf4j +public class SentinelFrameServiceImpl implements ISentinelFrameService { + + @Resource + private CasicProtocol protocol; + + @Resource + IDataSentinelOtherService sentinelDataService; + + @Resource + IDeviceWellViewService deviceService; + + public CasicFrame dataParse(String frame) { + // 1. 判断帧结构 + boolean frameValid = protocol.checkFrame(frame); + if (frameValid) { + // 2. 获取帧结构中的关键字段信息 + String deviceId = protocol.getDeviceId(frame); + String deviceType = protocol.getDeviceType(frame); + String messageType = protocol.getMessageType(frame); + String messageBody = protocol.getMessageBody(frame).toUpperCase(); + String uptime = protocol.getUptime(frame); + String sequence = protocol.getMessageSequence(frame); + + String manufacturerCode = protocol.getManufacturerCode(frame); + CasicFrame sentinelFrame = CasicFrameBuildFactory.buildCasicFrame(messageType, manufacturerCode, deviceType); + + if (sentinelFrame != null) { + sentinelFrame.setDeviceCode(deviceId); + sentinelFrame.setUptime(uptime); + sentinelFrame.setMessageType(messageType); + sentinelFrame.setSequence(sequence); + + // 心跳类的消息不解析MessageBody + if (!sentinelFrame.getMessageType().equals("00")) { + sentinelFrame.setMessageBody(protocol.parseMessageBody(messageBody)); + sentinelFrame.parseMessageBody(); + } + + log.info("收到设备消息:{}", sentinelFrame); + return sentinelFrame; + } + } else { + log.error("消息帧解析异常"); + } + + return null; + } + + @Override + public String replyMessage(String deviceCode, String sequence) { + CasicFrame reply = new ReplyFrame(); + reply.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + reply.setDeviceCode(deviceCode); + reply.setSequence(sequence); + reply.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + return protocol.buildReplyFrameStr(reply); + } + + @Override + public String doBuildCommand(CasicFrame cmd) { + return protocol.buildFrameStr(cmd); + } + + @Override + public void afterAction(CasicFrame frame) { + // 数据消息帧 进行存库操作 + if (frame instanceof DataFrame) { + String devCode = frame.getDeviceCode(); + DeviceWellView devWellView = deviceService.getDeviceWellViewByDevCode(devCode); + String wellCode = ""; + if (devWellView != null) { + wellCode = devWellView.getWellCode(); + } + List dataList = ((DataFrame) frame).toDataModelList(); + if (dataList != null) { + for (Serializable item : dataList) { + DataMonitorPipeOther data = (DataMonitorPipeOther) item; + data.setWellCode(wellCode); + sentinelDataService.save(data); + } + } + } + } +} diff --git a/src/main/java/com/casic/tube/controller/TubeDataController.java b/src/main/java/com/casic/tube/controller/TubeDataController.java index 61486c5..4965449 100644 --- a/src/main/java/com/casic/tube/controller/TubeDataController.java +++ b/src/main/java/com/casic/tube/controller/TubeDataController.java @@ -2,8 +2,8 @@ import com.alibaba.fastjson.JSONObject; import com.casic.common.CasicFrame; -import com.casic.tube.frame.ConfigFrame; -import com.casic.tube.service.ITubeDataService; +import com.casic.common.general.ConfigFrame; +import com.casic.tube.service.ITubeFrameService; import com.casic.util.aep.AepCommandSend; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestBody; @@ -21,7 +21,7 @@ public class TubeDataController { @Resource - private ITubeDataService tubeDataService; + private ITubeFrameService frameService; @RequestMapping("/tube/data/recv") public Object dataRecv(@RequestBody Map map) { @@ -42,10 +42,10 @@ String frameStr = new String(baseBytes); // 根据协议进行解析 - CasicFrame frame = tubeDataService.dataParse(frameStr); + CasicFrame frame = frameService.dataParse(frameStr); // 存库 - tubeDataService.afterAction(frame); + frameService.afterAction(frame); retObj.put("code", 200); retObj.put("success", true); @@ -74,7 +74,7 @@ messageBody.put("datas", map.get("cmdList")); cmdFrame.setMessageBody(messageBody); - String frameStr = tubeDataService.doBuildCommand(cmdFrame); + String frameStr = frameService.doBuildCommand(cmdFrame); // TODO-LIST // 这三个参数根据设备编号从数据库中取 diff --git a/src/main/java/com/casic/tube/frame/ConfigFrame.java b/src/main/java/com/casic/tube/frame/ConfigFrame.java deleted file mode 100644 index 883dad6..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigFrame.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigFrame extends CasicFrame { - - public ConfigFrame() { - setSequence("01"); // 默认序号 - setControl("1"); // 默认为不需要分包 - setMessageType("52"); // 消息大类 52 = SetRequest - } -} diff --git a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java b/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java deleted file mode 100644 index a419145..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigResponseFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "03"; - final String MESSAGE_TYPE_STRING = "SetResponse"; - final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "指令序号" + getSequence() + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/DataFrame.java b/src/main/java/com/casic/tube/frame/DataFrame.java deleted file mode 100644 index 97e07b8..0000000 --- a/src/main/java/com/casic/tube/frame/DataFrame.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import com.casic.dao.model.DataTubeOther; - -import java.util.List; - -public class DataFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "02"; - final String MESSAGE_TYPE_STRING = "Data/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "数据消息/管盯"; - - public List dataItemList; - - public List toDataModelList() { - return null; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append(";"); - builder.append("上报时间:").append(getUptime()).append(";"); - for (DataItem dataItem : dataItemList) { - builder.append("["); - builder.append(dataItem); - builder.append("],"); - } - builder.deleteCharAt(builder.length() - 1); - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/DataItem.java b/src/main/java/com/casic/tube/frame/DataItem.java deleted file mode 100644 index 4e9aceb..0000000 --- a/src/main/java/com/casic/tube/frame/DataItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class DataItem { -} diff --git a/src/main/java/com/casic/tube/frame/EventFrame.java b/src/main/java/com/casic/tube/frame/EventFrame.java deleted file mode 100644 index ea800b4..0000000 --- a/src/main/java/com/casic/tube/frame/EventFrame.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -import java.util.List; - -public class EventFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "01"; - final String MESSAGE_TYPE_STRING = "Event/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "事件消息/管盯"; - - public List eventItemList; - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append("; "); - builder.append("上报时间:").append(getUptime()).append("; "); - for (EventItem eventItem : eventItemList) { - builder.append("["); - builder.append(eventItem); - builder.append("],"); - } - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/EventItem.java b/src/main/java/com/casic/tube/frame/EventItem.java deleted file mode 100644 index a1245bf..0000000 --- a/src/main/java/com/casic/tube/frame/EventItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class EventItem { -} diff --git a/src/main/java/com/casic/tube/frame/HeartFrame.java b/src/main/java/com/casic/tube/frame/HeartFrame.java deleted file mode 100644 index af7e7a6..0000000 --- a/src/main/java/com/casic/tube/frame/HeartFrame.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; - -@Data -public class HeartFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "00"; - final String MESSAGE_TYPE_STRING = "OnlineRequest"; - final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/IMEIFrame.java b/src/main/java/com/casic/tube/frame/IMEIFrame.java deleted file mode 100644 index 9420620..0000000 --- a/src/main/java/com/casic/tube/frame/IMEIFrame.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; - -@Data -public class IMEIFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "05"; - final String MESSAGE_TYPE_STRING = "StartupRequest"; - final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; - - String imei; - String iccid; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "IMEI:" + imei + ";" + - "ICCID:" + iccid + - "}"; - } - - @Override - public void parseMessageBody() { - imei = getMessageBody().getString("IMEI"); - iccid = getMessageBody().getString("ICCID"); - } -} diff --git a/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java b/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java index 50e8a2b..47bf4d6 100644 --- a/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java @@ -3,11 +3,12 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.casic.dao.model.DataTubeOther; -import com.casic.tube.frame.DataFrame; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -19,7 +20,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override @@ -43,8 +45,8 @@ } @Override - public List toDataModelList() { - List dataList = new ArrayList<>(); + public List toDataModelList() { + List dataList = new ArrayList<>(); for (DataItem dataItem : dataItemList) { DataTubeOther data = new DataTubeOther(); diff --git a/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java b/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java index 8d09b10..75e94c7 100644 --- a/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.brs; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataItem; import lombok.Data; @Data diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java new file mode 100644 index 0000000..95d2bd4 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java @@ -0,0 +1,8 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.DataMonitorPipeOther; + +public interface IDataSentinelOtherService extends IService { + +} diff --git a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java index d6b1200..0290829 100644 --- a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java +++ b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java @@ -1,7 +1,6 @@ package com.casic.dao.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.dao.model.DataTubeOther; import com.casic.dao.model.DeviceWellView; public interface IDeviceWellViewService extends IService { diff --git a/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java new file mode 100644 index 0000000..be34f77 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java @@ -0,0 +1,16 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.BusDeviceMapper; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import org.springframework.stereotype.Service; + +@Service +public class BusDeviceServiceImpl extends ServiceImpl implements IBusDeviceService { + + @Override + public BusDevice getDeviceByCode(String devCode) { + return baseMapper.getOneByDevCode(devCode); + } +} diff --git a/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java new file mode 100644 index 0000000..0db2007 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java @@ -0,0 +1,11 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.DataSentinelOtherMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.service.IDataSentinelOtherService; +import org.springframework.stereotype.Service; + +@Service +public class DataSentinelOtherServiceImpl extends ServiceImpl implements IDataSentinelOtherService { +} diff --git a/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java new file mode 100644 index 0000000..d8c5ef2 --- /dev/null +++ b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java @@ -0,0 +1,111 @@ +package com.casic.protocol; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.CasicProtocol; +import org.springframework.stereotype.Component; + +@Component +public class CasicTubeProtocolImpl implements CasicProtocol { + @Override + public boolean checkFrame(String frame) { + boolean valid = checkFrameHeaderAndTail(frame); + if (valid) { + valid = checkFrameLength(frame); + } + + return valid; + } + + private boolean checkFrameHeaderAndTail(String frame) { + return (frame.substring(0, 2).equalsIgnoreCase("AA")) && + (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); + } + + private boolean checkFrameLength(String frame) { + String lengthStr = frame.substring(4, 7); + int length = Integer.parseInt(lengthStr); + + return frame.length() == length + 9; + } + + @Override + public String getDeviceType(String frame) { + return frame.substring(7, 9); + } + + @Override + public String getDeviceId(String frame) { + return frame.substring(9, 21); + } + + @Override + public String getManufacturerCode(String frame) { + return frame.substring(11, 13); + } + + @Override + public String getMessageType(String frame) { + return frame.substring(21, 23); + } + + @Override + public String getMessageSequence(String frame) { + return frame.substring(23, 25); + } + + @Override + public String getMessageBody(String frame) { + return frame.substring(26, frame.length() - 16); + } + + @Override + public JSONObject parseMessageBody(String messageBody) { + return JSONObject.parseObject(messageBody); + } + + @Override + public String getUptime(String frame) { + return frame.substring(frame.length() - 16, frame.length() - 2); + } + + @Override + public String buildFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append(frame.getMessageBody().toJSONString()); + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } + + @Override + public String buildReplyFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append("00"); // 消息响应类消息 消息体为00 + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/senitnel/controller/SentinelDataController.java b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java new file mode 100644 index 0000000..633c072 --- /dev/null +++ b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java @@ -0,0 +1,120 @@ +package com.casic.senitnel.controller; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.general.ConfigFrame; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import com.casic.senitnel.service.ISentinelFrameService; +import com.casic.util.aep.AepCommandSend; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Base64; +import java.util.Map; + +@Slf4j +@RestController +public class SentinelDataController { + + @Resource + private ISentinelFrameService frameService; + + @Resource + private IBusDeviceService deviceService; + + @RequestMapping("/sentinel/data/recv") + public Object dataRecv(@RequestBody Map map) { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + + JSONObject recvObj = (JSONObject) JSONObject.toJSON(map); + if (recvObj.containsKey("payload")) { + JSONObject payload = recvObj.getJSONObject("payload"); + String value = payload.getString("APPdata"); + + if (value.isEmpty()) { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } else { + byte[] baseBytes = Base64.getDecoder().decode(value); + String frameStr = new String(baseBytes); + + // 根据协议进行解析 + CasicFrame frame = frameService.dataParse(frameStr); + + if (frame != null) { + // 回复响应 + String replyFrameStr = frameService.replyMessage(frame.getDeviceCode(), frame.getSequence()); + + // 从数据库中获取master-api-key 回复响应消息 + BusDevice device = deviceService.getDeviceByCode(frame.getDeviceCode()); + if (device != null && StringUtils.isNotBlank(device.getMasterApiKey())) { + String masterApiKey = device.getMasterApiKey(); + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + + try { + int code = aepCommandSend.handleAndReply(replyFrameStr); + } catch (Exception ex) { + log.error("向设备回复响应异常:{}", ex.getMessage()); + } + } + + // 存库 + frameService.afterAction(frame); + } + + retObj.put("code", 200); + retObj.put("success", true); + } + } else { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } + + return retObj; + } + + @RequestMapping("/sentinel/config/send") + public Object configSend(@RequestBody Map map) throws Exception { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + CasicFrame cmdFrame = new ConfigFrame(); + cmdFrame.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + cmdFrame.setDeviceCode((String) map.get("devCode")); + cmdFrame.setSequence("01"); + cmdFrame.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + JSONObject messageBody = new JSONObject(); + messageBody.put("datas", map.get("cmdList")); + cmdFrame.setMessageBody(messageBody); + + String frameStr = frameService.doBuildCommand(cmdFrame); + + // TODO-LIST + // 这三个参数根据设备编号从数据库中取 + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + String masterApiKey = (String) map.get("masterApiKey"); + + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + int code = aepCommandSend.handleAndReply(frameStr); + + retObj.put("code", 200); + retObj.put("success", true); + retObj.put("AEPRetCode", code); + return retObj; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java new file mode 100644 index 0000000..368af03 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java @@ -0,0 +1,82 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; +import com.casic.dao.model.DataMonitorPipeOther; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class DataFrameNCX extends DataFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + dataItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + DataItemNCX dataItem = new DataItemNCX(); + + dataItem.setLenL(dataObj.getString("LENGL")); + dataItem.setLenR(dataObj.getString("LENGR")); + dataItem.setBat(dataObj.getString("BAT")); + dataItem.setCh4L(dataObj.getString("CH4L")); + dataItem.setCh4R(dataObj.getString("CH4R")); + dataItem.setSlope(dataObj.getString("SLOPING")); + dataItem.setDestroy(dataObj.getString("DESTROY")); + dataItem.setLeak(dataObj.getString("LEAK")); + dataItem.setDiscL(dataObj.getString("DISCL")); + dataItem.setDiscR(dataObj.getString("DISCR")); + dataItem.setVibL(dataObj.getString("VIBL")); + dataItem.setVibR(dataObj.getString("VIBR")); + dataItem.setTime(dataObj.getString("UPTIME")); + + dataItemList.add(dataItem); + } + } + + @Override + public List toDataModelList() { + List dataList = new ArrayList<>(); + for (DataItem dataItem : dataItemList) { + DataMonitorPipeOther data = new DataMonitorPipeOther(); + + data.setDevcode(getDeviceCode()); + data.setLeftLength(((DataItemNCX)dataItem).getLenL()); + data.setRightLength(((DataItemNCX)dataItem).getLenR()); + data.setLeftGas(((DataItemNCX)dataItem).getCh4L()); + data.setRightGas(((DataItemNCX)dataItem).getCh4R()); + data.setVbat(((DataItemNCX)dataItem).getBat()); + data.setPipeInclineAlarm(((DataItemNCX)dataItem).getSlope()); + data.setPipeBreakAlarm(((DataItemNCX)dataItem).getDestroy()); + data.setGasAlarm(((DataItemNCX)dataItem).getLeak()); + data.setLeftOfflineAlarm(((DataItemNCX)dataItem).getDiscL()); + data.setRightOfflineAlarm(((DataItemNCX)dataItem).getDiscR()); + data.setLeftVibrateAlarm(((DataItemNCX)dataItem).getVibL()); + data.setRightVibrateAlarm(((DataItemNCX)dataItem).getVibR()); + data.setUptime(LocalDateTime.parse(((DataItemNCX)dataItem).getTime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 采集时间 + data.setLogtime(LocalDateTime.parse(getUptime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 上报时间 + + dataList.add(data); + } + + return dataList; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java new file mode 100644 index 0000000..372ac73 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java @@ -0,0 +1,31 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.DataItem; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class DataItemNCX extends DataItem { + String lenL; // 左侧指示带长度 + String lenR; // 右侧指示带长度 + String ch4L; // 左侧甲烷浓度值 + String ch4R; // 右侧甲烷浓度值 + String bat; // 电池电压 + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String spare; // 备用 + String time; // 采集时间 + + @Override + public String toString() { + return "气体浓度值:" + "(" + ch4L + "," + ch4R + ")" + "%LEL;" + + "电池电压值:" + bat + "v;" + + "采样时间:" + time; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java new file mode 100644 index 0000000..b3bbcf4 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java @@ -0,0 +1,43 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.EventFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class EventFrameNCX extends EventFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + eventItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + EventItemNCX eventItem = new EventItemNCX(); + + eventItem.setSlope(dataObj.getString("SLOPING")); + eventItem.setDestroy(dataObj.getString("DESTROY")); + eventItem.setLeak(dataObj.getString("LEAK")); + eventItem.setDiscL(dataObj.getString("DISCL")); + eventItem.setDiscR(dataObj.getString("DISCR")); + eventItem.setVibL(dataObj.getString("VIBL")); + eventItem.setVibR(dataObj.getString("VIBR")); + eventItem.setTime(dataObj.getString("UPTIME")); + + eventItemList.add(eventItem); + } + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java new file mode 100644 index 0000000..1a560d0 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java @@ -0,0 +1,49 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.EventItem; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.commons.lang3.StringUtils; + +@EqualsAndHashCode(callSuper = true) +@Data +public class EventItemNCX extends EventItem { + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String time; // 采集时间 + + @Override + public String toString() { + String str = ""; + if (StringUtils.isNotBlank(slope) && slope.equalsIgnoreCase("1")) { + str += "[倾斜报警]"; + } + if (StringUtils.isNotBlank(destroy) && destroy.equalsIgnoreCase("1")) { + str += "[破坏报警]"; + } + if (StringUtils.isNotBlank(leak) && leak.equalsIgnoreCase("1")) { + str += "[甲烷泄漏报警]"; + } + if (StringUtils.isNotBlank(discL) && discL.equalsIgnoreCase("1")) { + str += "[左侧断线报警]"; + } + if (StringUtils.isNotBlank(discR) && discR.equalsIgnoreCase("1")) { + str += "[右侧断线报警]"; + } + if (StringUtils.isNotBlank(vibL) && vibL.equalsIgnoreCase("1")) { + str += "[左侧振动报警]"; + } + if (StringUtils.isNotBlank(vibR) && vibR.equalsIgnoreCase("1")) { + str += "[右侧振动报警]"; + } + str += "采样时间:" + time; + + return str; + + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java new file mode 100644 index 0000000..343c4d6 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java @@ -0,0 +1,37 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class InfoFrameNCX extends CasicFrame { + + String workMode; + String model; + String hwVersion; + String softVersion; + String sensorType; + + @Override + public String toString() { + return "设备编号: " + getDeviceCode() + "; " + + "设备工作模式: " + workMode + " ; " + + "设备型号: " + model + " ; " + + "版本号: " + hwVersion + ", " + softVersion + "; " + + "传感器类型: " + sensorType + " ; " + + "上报时间: " + getUptime(); + } + + @Override + public void parseMessageBody() { + workMode = getMessageBody().getString("WORKMODE"); + model = getMessageBody().getString("MODEL"); + hwVersion = getMessageBody().getString("HWVERSION"); + softVersion = getMessageBody().getString("SOFTVERSION"); + sensorType = getMessageBody().getString("SENSORTYPE"); + } +} diff --git a/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java new file mode 100644 index 0000000..e76fc86 --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java @@ -0,0 +1,14 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; + +public interface ISentinelFrameService { + + CasicFrame dataParse(String frame); + + String replyMessage(String deviceCode, String sequence); + + String doBuildCommand(CasicFrame cmd); + + void afterAction(CasicFrame frame); +} diff --git a/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java new file mode 100644 index 0000000..803ff0e --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java @@ -0,0 +1,109 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; +import com.casic.common.CasicFrameBuildFactory; +import com.casic.common.CasicProtocol; +import com.casic.common.general.DataFrame; +import com.casic.common.general.EventFrame; +import com.casic.common.general.ReplyFrame; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.model.DeviceWellView; +import com.casic.dao.service.IDataSentinelOtherService; +import com.casic.dao.service.IDeviceWellViewService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + + +@Service +@Slf4j +public class SentinelFrameServiceImpl implements ISentinelFrameService { + + @Resource + private CasicProtocol protocol; + + @Resource + IDataSentinelOtherService sentinelDataService; + + @Resource + IDeviceWellViewService deviceService; + + public CasicFrame dataParse(String frame) { + // 1. 判断帧结构 + boolean frameValid = protocol.checkFrame(frame); + if (frameValid) { + // 2. 获取帧结构中的关键字段信息 + String deviceId = protocol.getDeviceId(frame); + String deviceType = protocol.getDeviceType(frame); + String messageType = protocol.getMessageType(frame); + String messageBody = protocol.getMessageBody(frame).toUpperCase(); + String uptime = protocol.getUptime(frame); + String sequence = protocol.getMessageSequence(frame); + + String manufacturerCode = protocol.getManufacturerCode(frame); + CasicFrame sentinelFrame = CasicFrameBuildFactory.buildCasicFrame(messageType, manufacturerCode, deviceType); + + if (sentinelFrame != null) { + sentinelFrame.setDeviceCode(deviceId); + sentinelFrame.setUptime(uptime); + sentinelFrame.setMessageType(messageType); + sentinelFrame.setSequence(sequence); + + // 心跳类的消息不解析MessageBody + if (!sentinelFrame.getMessageType().equals("00")) { + sentinelFrame.setMessageBody(protocol.parseMessageBody(messageBody)); + sentinelFrame.parseMessageBody(); + } + + log.info("收到设备消息:{}", sentinelFrame); + return sentinelFrame; + } + } else { + log.error("消息帧解析异常"); + } + + return null; + } + + @Override + public String replyMessage(String deviceCode, String sequence) { + CasicFrame reply = new ReplyFrame(); + reply.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + reply.setDeviceCode(deviceCode); + reply.setSequence(sequence); + reply.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + return protocol.buildReplyFrameStr(reply); + } + + @Override + public String doBuildCommand(CasicFrame cmd) { + return protocol.buildFrameStr(cmd); + } + + @Override + public void afterAction(CasicFrame frame) { + // 数据消息帧 进行存库操作 + if (frame instanceof DataFrame) { + String devCode = frame.getDeviceCode(); + DeviceWellView devWellView = deviceService.getDeviceWellViewByDevCode(devCode); + String wellCode = ""; + if (devWellView != null) { + wellCode = devWellView.getWellCode(); + } + List dataList = ((DataFrame) frame).toDataModelList(); + if (dataList != null) { + for (Serializable item : dataList) { + DataMonitorPipeOther data = (DataMonitorPipeOther) item; + data.setWellCode(wellCode); + sentinelDataService.save(data); + } + } + } + } +} diff --git a/src/main/java/com/casic/tube/controller/TubeDataController.java b/src/main/java/com/casic/tube/controller/TubeDataController.java index 61486c5..4965449 100644 --- a/src/main/java/com/casic/tube/controller/TubeDataController.java +++ b/src/main/java/com/casic/tube/controller/TubeDataController.java @@ -2,8 +2,8 @@ import com.alibaba.fastjson.JSONObject; import com.casic.common.CasicFrame; -import com.casic.tube.frame.ConfigFrame; -import com.casic.tube.service.ITubeDataService; +import com.casic.common.general.ConfigFrame; +import com.casic.tube.service.ITubeFrameService; import com.casic.util.aep.AepCommandSend; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestBody; @@ -21,7 +21,7 @@ public class TubeDataController { @Resource - private ITubeDataService tubeDataService; + private ITubeFrameService frameService; @RequestMapping("/tube/data/recv") public Object dataRecv(@RequestBody Map map) { @@ -42,10 +42,10 @@ String frameStr = new String(baseBytes); // 根据协议进行解析 - CasicFrame frame = tubeDataService.dataParse(frameStr); + CasicFrame frame = frameService.dataParse(frameStr); // 存库 - tubeDataService.afterAction(frame); + frameService.afterAction(frame); retObj.put("code", 200); retObj.put("success", true); @@ -74,7 +74,7 @@ messageBody.put("datas", map.get("cmdList")); cmdFrame.setMessageBody(messageBody); - String frameStr = tubeDataService.doBuildCommand(cmdFrame); + String frameStr = frameService.doBuildCommand(cmdFrame); // TODO-LIST // 这三个参数根据设备编号从数据库中取 diff --git a/src/main/java/com/casic/tube/frame/ConfigFrame.java b/src/main/java/com/casic/tube/frame/ConfigFrame.java deleted file mode 100644 index 883dad6..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigFrame.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigFrame extends CasicFrame { - - public ConfigFrame() { - setSequence("01"); // 默认序号 - setControl("1"); // 默认为不需要分包 - setMessageType("52"); // 消息大类 52 = SetRequest - } -} diff --git a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java b/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java deleted file mode 100644 index a419145..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigResponseFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "03"; - final String MESSAGE_TYPE_STRING = "SetResponse"; - final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "指令序号" + getSequence() + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/DataFrame.java b/src/main/java/com/casic/tube/frame/DataFrame.java deleted file mode 100644 index 97e07b8..0000000 --- a/src/main/java/com/casic/tube/frame/DataFrame.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import com.casic.dao.model.DataTubeOther; - -import java.util.List; - -public class DataFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "02"; - final String MESSAGE_TYPE_STRING = "Data/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "数据消息/管盯"; - - public List dataItemList; - - public List toDataModelList() { - return null; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append(";"); - builder.append("上报时间:").append(getUptime()).append(";"); - for (DataItem dataItem : dataItemList) { - builder.append("["); - builder.append(dataItem); - builder.append("],"); - } - builder.deleteCharAt(builder.length() - 1); - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/DataItem.java b/src/main/java/com/casic/tube/frame/DataItem.java deleted file mode 100644 index 4e9aceb..0000000 --- a/src/main/java/com/casic/tube/frame/DataItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class DataItem { -} diff --git a/src/main/java/com/casic/tube/frame/EventFrame.java b/src/main/java/com/casic/tube/frame/EventFrame.java deleted file mode 100644 index ea800b4..0000000 --- a/src/main/java/com/casic/tube/frame/EventFrame.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -import java.util.List; - -public class EventFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "01"; - final String MESSAGE_TYPE_STRING = "Event/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "事件消息/管盯"; - - public List eventItemList; - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append("; "); - builder.append("上报时间:").append(getUptime()).append("; "); - for (EventItem eventItem : eventItemList) { - builder.append("["); - builder.append(eventItem); - builder.append("],"); - } - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/EventItem.java b/src/main/java/com/casic/tube/frame/EventItem.java deleted file mode 100644 index a1245bf..0000000 --- a/src/main/java/com/casic/tube/frame/EventItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class EventItem { -} diff --git a/src/main/java/com/casic/tube/frame/HeartFrame.java b/src/main/java/com/casic/tube/frame/HeartFrame.java deleted file mode 100644 index af7e7a6..0000000 --- a/src/main/java/com/casic/tube/frame/HeartFrame.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; - -@Data -public class HeartFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "00"; - final String MESSAGE_TYPE_STRING = "OnlineRequest"; - final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/IMEIFrame.java b/src/main/java/com/casic/tube/frame/IMEIFrame.java deleted file mode 100644 index 9420620..0000000 --- a/src/main/java/com/casic/tube/frame/IMEIFrame.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; - -@Data -public class IMEIFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "05"; - final String MESSAGE_TYPE_STRING = "StartupRequest"; - final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; - - String imei; - String iccid; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "IMEI:" + imei + ";" + - "ICCID:" + iccid + - "}"; - } - - @Override - public void parseMessageBody() { - imei = getMessageBody().getString("IMEI"); - iccid = getMessageBody().getString("ICCID"); - } -} diff --git a/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java b/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java index 50e8a2b..47bf4d6 100644 --- a/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java @@ -3,11 +3,12 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.casic.dao.model.DataTubeOther; -import com.casic.tube.frame.DataFrame; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -19,7 +20,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override @@ -43,8 +45,8 @@ } @Override - public List toDataModelList() { - List dataList = new ArrayList<>(); + public List toDataModelList() { + List dataList = new ArrayList<>(); for (DataItem dataItem : dataItemList) { DataTubeOther data = new DataTubeOther(); diff --git a/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java b/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java index 8d09b10..75e94c7 100644 --- a/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.brs; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java b/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java index 9026b4c..2e5c145 100644 --- a/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java @@ -2,14 +2,11 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.casic.common.CasicFrame; -import com.casic.tube.frame.EventFrame; -import com.casic.tube.frame.EventItem; +import com.casic.common.general.EventFrame; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; -import java.util.List; @Data @Slf4j @@ -17,7 +14,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java new file mode 100644 index 0000000..95d2bd4 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java @@ -0,0 +1,8 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.DataMonitorPipeOther; + +public interface IDataSentinelOtherService extends IService { + +} diff --git a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java index d6b1200..0290829 100644 --- a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java +++ b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java @@ -1,7 +1,6 @@ package com.casic.dao.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.dao.model.DataTubeOther; import com.casic.dao.model.DeviceWellView; public interface IDeviceWellViewService extends IService { diff --git a/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java new file mode 100644 index 0000000..be34f77 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java @@ -0,0 +1,16 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.BusDeviceMapper; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import org.springframework.stereotype.Service; + +@Service +public class BusDeviceServiceImpl extends ServiceImpl implements IBusDeviceService { + + @Override + public BusDevice getDeviceByCode(String devCode) { + return baseMapper.getOneByDevCode(devCode); + } +} diff --git a/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java new file mode 100644 index 0000000..0db2007 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java @@ -0,0 +1,11 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.DataSentinelOtherMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.service.IDataSentinelOtherService; +import org.springframework.stereotype.Service; + +@Service +public class DataSentinelOtherServiceImpl extends ServiceImpl implements IDataSentinelOtherService { +} diff --git a/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java new file mode 100644 index 0000000..d8c5ef2 --- /dev/null +++ b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java @@ -0,0 +1,111 @@ +package com.casic.protocol; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.CasicProtocol; +import org.springframework.stereotype.Component; + +@Component +public class CasicTubeProtocolImpl implements CasicProtocol { + @Override + public boolean checkFrame(String frame) { + boolean valid = checkFrameHeaderAndTail(frame); + if (valid) { + valid = checkFrameLength(frame); + } + + return valid; + } + + private boolean checkFrameHeaderAndTail(String frame) { + return (frame.substring(0, 2).equalsIgnoreCase("AA")) && + (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); + } + + private boolean checkFrameLength(String frame) { + String lengthStr = frame.substring(4, 7); + int length = Integer.parseInt(lengthStr); + + return frame.length() == length + 9; + } + + @Override + public String getDeviceType(String frame) { + return frame.substring(7, 9); + } + + @Override + public String getDeviceId(String frame) { + return frame.substring(9, 21); + } + + @Override + public String getManufacturerCode(String frame) { + return frame.substring(11, 13); + } + + @Override + public String getMessageType(String frame) { + return frame.substring(21, 23); + } + + @Override + public String getMessageSequence(String frame) { + return frame.substring(23, 25); + } + + @Override + public String getMessageBody(String frame) { + return frame.substring(26, frame.length() - 16); + } + + @Override + public JSONObject parseMessageBody(String messageBody) { + return JSONObject.parseObject(messageBody); + } + + @Override + public String getUptime(String frame) { + return frame.substring(frame.length() - 16, frame.length() - 2); + } + + @Override + public String buildFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append(frame.getMessageBody().toJSONString()); + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } + + @Override + public String buildReplyFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append("00"); // 消息响应类消息 消息体为00 + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/senitnel/controller/SentinelDataController.java b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java new file mode 100644 index 0000000..633c072 --- /dev/null +++ b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java @@ -0,0 +1,120 @@ +package com.casic.senitnel.controller; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.general.ConfigFrame; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import com.casic.senitnel.service.ISentinelFrameService; +import com.casic.util.aep.AepCommandSend; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Base64; +import java.util.Map; + +@Slf4j +@RestController +public class SentinelDataController { + + @Resource + private ISentinelFrameService frameService; + + @Resource + private IBusDeviceService deviceService; + + @RequestMapping("/sentinel/data/recv") + public Object dataRecv(@RequestBody Map map) { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + + JSONObject recvObj = (JSONObject) JSONObject.toJSON(map); + if (recvObj.containsKey("payload")) { + JSONObject payload = recvObj.getJSONObject("payload"); + String value = payload.getString("APPdata"); + + if (value.isEmpty()) { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } else { + byte[] baseBytes = Base64.getDecoder().decode(value); + String frameStr = new String(baseBytes); + + // 根据协议进行解析 + CasicFrame frame = frameService.dataParse(frameStr); + + if (frame != null) { + // 回复响应 + String replyFrameStr = frameService.replyMessage(frame.getDeviceCode(), frame.getSequence()); + + // 从数据库中获取master-api-key 回复响应消息 + BusDevice device = deviceService.getDeviceByCode(frame.getDeviceCode()); + if (device != null && StringUtils.isNotBlank(device.getMasterApiKey())) { + String masterApiKey = device.getMasterApiKey(); + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + + try { + int code = aepCommandSend.handleAndReply(replyFrameStr); + } catch (Exception ex) { + log.error("向设备回复响应异常:{}", ex.getMessage()); + } + } + + // 存库 + frameService.afterAction(frame); + } + + retObj.put("code", 200); + retObj.put("success", true); + } + } else { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } + + return retObj; + } + + @RequestMapping("/sentinel/config/send") + public Object configSend(@RequestBody Map map) throws Exception { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + CasicFrame cmdFrame = new ConfigFrame(); + cmdFrame.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + cmdFrame.setDeviceCode((String) map.get("devCode")); + cmdFrame.setSequence("01"); + cmdFrame.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + JSONObject messageBody = new JSONObject(); + messageBody.put("datas", map.get("cmdList")); + cmdFrame.setMessageBody(messageBody); + + String frameStr = frameService.doBuildCommand(cmdFrame); + + // TODO-LIST + // 这三个参数根据设备编号从数据库中取 + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + String masterApiKey = (String) map.get("masterApiKey"); + + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + int code = aepCommandSend.handleAndReply(frameStr); + + retObj.put("code", 200); + retObj.put("success", true); + retObj.put("AEPRetCode", code); + return retObj; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java new file mode 100644 index 0000000..368af03 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java @@ -0,0 +1,82 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; +import com.casic.dao.model.DataMonitorPipeOther; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class DataFrameNCX extends DataFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + dataItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + DataItemNCX dataItem = new DataItemNCX(); + + dataItem.setLenL(dataObj.getString("LENGL")); + dataItem.setLenR(dataObj.getString("LENGR")); + dataItem.setBat(dataObj.getString("BAT")); + dataItem.setCh4L(dataObj.getString("CH4L")); + dataItem.setCh4R(dataObj.getString("CH4R")); + dataItem.setSlope(dataObj.getString("SLOPING")); + dataItem.setDestroy(dataObj.getString("DESTROY")); + dataItem.setLeak(dataObj.getString("LEAK")); + dataItem.setDiscL(dataObj.getString("DISCL")); + dataItem.setDiscR(dataObj.getString("DISCR")); + dataItem.setVibL(dataObj.getString("VIBL")); + dataItem.setVibR(dataObj.getString("VIBR")); + dataItem.setTime(dataObj.getString("UPTIME")); + + dataItemList.add(dataItem); + } + } + + @Override + public List toDataModelList() { + List dataList = new ArrayList<>(); + for (DataItem dataItem : dataItemList) { + DataMonitorPipeOther data = new DataMonitorPipeOther(); + + data.setDevcode(getDeviceCode()); + data.setLeftLength(((DataItemNCX)dataItem).getLenL()); + data.setRightLength(((DataItemNCX)dataItem).getLenR()); + data.setLeftGas(((DataItemNCX)dataItem).getCh4L()); + data.setRightGas(((DataItemNCX)dataItem).getCh4R()); + data.setVbat(((DataItemNCX)dataItem).getBat()); + data.setPipeInclineAlarm(((DataItemNCX)dataItem).getSlope()); + data.setPipeBreakAlarm(((DataItemNCX)dataItem).getDestroy()); + data.setGasAlarm(((DataItemNCX)dataItem).getLeak()); + data.setLeftOfflineAlarm(((DataItemNCX)dataItem).getDiscL()); + data.setRightOfflineAlarm(((DataItemNCX)dataItem).getDiscR()); + data.setLeftVibrateAlarm(((DataItemNCX)dataItem).getVibL()); + data.setRightVibrateAlarm(((DataItemNCX)dataItem).getVibR()); + data.setUptime(LocalDateTime.parse(((DataItemNCX)dataItem).getTime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 采集时间 + data.setLogtime(LocalDateTime.parse(getUptime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 上报时间 + + dataList.add(data); + } + + return dataList; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java new file mode 100644 index 0000000..372ac73 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java @@ -0,0 +1,31 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.DataItem; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class DataItemNCX extends DataItem { + String lenL; // 左侧指示带长度 + String lenR; // 右侧指示带长度 + String ch4L; // 左侧甲烷浓度值 + String ch4R; // 右侧甲烷浓度值 + String bat; // 电池电压 + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String spare; // 备用 + String time; // 采集时间 + + @Override + public String toString() { + return "气体浓度值:" + "(" + ch4L + "," + ch4R + ")" + "%LEL;" + + "电池电压值:" + bat + "v;" + + "采样时间:" + time; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java new file mode 100644 index 0000000..b3bbcf4 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java @@ -0,0 +1,43 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.EventFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class EventFrameNCX extends EventFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + eventItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + EventItemNCX eventItem = new EventItemNCX(); + + eventItem.setSlope(dataObj.getString("SLOPING")); + eventItem.setDestroy(dataObj.getString("DESTROY")); + eventItem.setLeak(dataObj.getString("LEAK")); + eventItem.setDiscL(dataObj.getString("DISCL")); + eventItem.setDiscR(dataObj.getString("DISCR")); + eventItem.setVibL(dataObj.getString("VIBL")); + eventItem.setVibR(dataObj.getString("VIBR")); + eventItem.setTime(dataObj.getString("UPTIME")); + + eventItemList.add(eventItem); + } + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java new file mode 100644 index 0000000..1a560d0 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java @@ -0,0 +1,49 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.EventItem; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.commons.lang3.StringUtils; + +@EqualsAndHashCode(callSuper = true) +@Data +public class EventItemNCX extends EventItem { + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String time; // 采集时间 + + @Override + public String toString() { + String str = ""; + if (StringUtils.isNotBlank(slope) && slope.equalsIgnoreCase("1")) { + str += "[倾斜报警]"; + } + if (StringUtils.isNotBlank(destroy) && destroy.equalsIgnoreCase("1")) { + str += "[破坏报警]"; + } + if (StringUtils.isNotBlank(leak) && leak.equalsIgnoreCase("1")) { + str += "[甲烷泄漏报警]"; + } + if (StringUtils.isNotBlank(discL) && discL.equalsIgnoreCase("1")) { + str += "[左侧断线报警]"; + } + if (StringUtils.isNotBlank(discR) && discR.equalsIgnoreCase("1")) { + str += "[右侧断线报警]"; + } + if (StringUtils.isNotBlank(vibL) && vibL.equalsIgnoreCase("1")) { + str += "[左侧振动报警]"; + } + if (StringUtils.isNotBlank(vibR) && vibR.equalsIgnoreCase("1")) { + str += "[右侧振动报警]"; + } + str += "采样时间:" + time; + + return str; + + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java new file mode 100644 index 0000000..343c4d6 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java @@ -0,0 +1,37 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class InfoFrameNCX extends CasicFrame { + + String workMode; + String model; + String hwVersion; + String softVersion; + String sensorType; + + @Override + public String toString() { + return "设备编号: " + getDeviceCode() + "; " + + "设备工作模式: " + workMode + " ; " + + "设备型号: " + model + " ; " + + "版本号: " + hwVersion + ", " + softVersion + "; " + + "传感器类型: " + sensorType + " ; " + + "上报时间: " + getUptime(); + } + + @Override + public void parseMessageBody() { + workMode = getMessageBody().getString("WORKMODE"); + model = getMessageBody().getString("MODEL"); + hwVersion = getMessageBody().getString("HWVERSION"); + softVersion = getMessageBody().getString("SOFTVERSION"); + sensorType = getMessageBody().getString("SENSORTYPE"); + } +} diff --git a/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java new file mode 100644 index 0000000..e76fc86 --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java @@ -0,0 +1,14 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; + +public interface ISentinelFrameService { + + CasicFrame dataParse(String frame); + + String replyMessage(String deviceCode, String sequence); + + String doBuildCommand(CasicFrame cmd); + + void afterAction(CasicFrame frame); +} diff --git a/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java new file mode 100644 index 0000000..803ff0e --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java @@ -0,0 +1,109 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; +import com.casic.common.CasicFrameBuildFactory; +import com.casic.common.CasicProtocol; +import com.casic.common.general.DataFrame; +import com.casic.common.general.EventFrame; +import com.casic.common.general.ReplyFrame; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.model.DeviceWellView; +import com.casic.dao.service.IDataSentinelOtherService; +import com.casic.dao.service.IDeviceWellViewService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + + +@Service +@Slf4j +public class SentinelFrameServiceImpl implements ISentinelFrameService { + + @Resource + private CasicProtocol protocol; + + @Resource + IDataSentinelOtherService sentinelDataService; + + @Resource + IDeviceWellViewService deviceService; + + public CasicFrame dataParse(String frame) { + // 1. 判断帧结构 + boolean frameValid = protocol.checkFrame(frame); + if (frameValid) { + // 2. 获取帧结构中的关键字段信息 + String deviceId = protocol.getDeviceId(frame); + String deviceType = protocol.getDeviceType(frame); + String messageType = protocol.getMessageType(frame); + String messageBody = protocol.getMessageBody(frame).toUpperCase(); + String uptime = protocol.getUptime(frame); + String sequence = protocol.getMessageSequence(frame); + + String manufacturerCode = protocol.getManufacturerCode(frame); + CasicFrame sentinelFrame = CasicFrameBuildFactory.buildCasicFrame(messageType, manufacturerCode, deviceType); + + if (sentinelFrame != null) { + sentinelFrame.setDeviceCode(deviceId); + sentinelFrame.setUptime(uptime); + sentinelFrame.setMessageType(messageType); + sentinelFrame.setSequence(sequence); + + // 心跳类的消息不解析MessageBody + if (!sentinelFrame.getMessageType().equals("00")) { + sentinelFrame.setMessageBody(protocol.parseMessageBody(messageBody)); + sentinelFrame.parseMessageBody(); + } + + log.info("收到设备消息:{}", sentinelFrame); + return sentinelFrame; + } + } else { + log.error("消息帧解析异常"); + } + + return null; + } + + @Override + public String replyMessage(String deviceCode, String sequence) { + CasicFrame reply = new ReplyFrame(); + reply.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + reply.setDeviceCode(deviceCode); + reply.setSequence(sequence); + reply.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + return protocol.buildReplyFrameStr(reply); + } + + @Override + public String doBuildCommand(CasicFrame cmd) { + return protocol.buildFrameStr(cmd); + } + + @Override + public void afterAction(CasicFrame frame) { + // 数据消息帧 进行存库操作 + if (frame instanceof DataFrame) { + String devCode = frame.getDeviceCode(); + DeviceWellView devWellView = deviceService.getDeviceWellViewByDevCode(devCode); + String wellCode = ""; + if (devWellView != null) { + wellCode = devWellView.getWellCode(); + } + List dataList = ((DataFrame) frame).toDataModelList(); + if (dataList != null) { + for (Serializable item : dataList) { + DataMonitorPipeOther data = (DataMonitorPipeOther) item; + data.setWellCode(wellCode); + sentinelDataService.save(data); + } + } + } + } +} diff --git a/src/main/java/com/casic/tube/controller/TubeDataController.java b/src/main/java/com/casic/tube/controller/TubeDataController.java index 61486c5..4965449 100644 --- a/src/main/java/com/casic/tube/controller/TubeDataController.java +++ b/src/main/java/com/casic/tube/controller/TubeDataController.java @@ -2,8 +2,8 @@ import com.alibaba.fastjson.JSONObject; import com.casic.common.CasicFrame; -import com.casic.tube.frame.ConfigFrame; -import com.casic.tube.service.ITubeDataService; +import com.casic.common.general.ConfigFrame; +import com.casic.tube.service.ITubeFrameService; import com.casic.util.aep.AepCommandSend; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestBody; @@ -21,7 +21,7 @@ public class TubeDataController { @Resource - private ITubeDataService tubeDataService; + private ITubeFrameService frameService; @RequestMapping("/tube/data/recv") public Object dataRecv(@RequestBody Map map) { @@ -42,10 +42,10 @@ String frameStr = new String(baseBytes); // 根据协议进行解析 - CasicFrame frame = tubeDataService.dataParse(frameStr); + CasicFrame frame = frameService.dataParse(frameStr); // 存库 - tubeDataService.afterAction(frame); + frameService.afterAction(frame); retObj.put("code", 200); retObj.put("success", true); @@ -74,7 +74,7 @@ messageBody.put("datas", map.get("cmdList")); cmdFrame.setMessageBody(messageBody); - String frameStr = tubeDataService.doBuildCommand(cmdFrame); + String frameStr = frameService.doBuildCommand(cmdFrame); // TODO-LIST // 这三个参数根据设备编号从数据库中取 diff --git a/src/main/java/com/casic/tube/frame/ConfigFrame.java b/src/main/java/com/casic/tube/frame/ConfigFrame.java deleted file mode 100644 index 883dad6..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigFrame.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigFrame extends CasicFrame { - - public ConfigFrame() { - setSequence("01"); // 默认序号 - setControl("1"); // 默认为不需要分包 - setMessageType("52"); // 消息大类 52 = SetRequest - } -} diff --git a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java b/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java deleted file mode 100644 index a419145..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigResponseFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "03"; - final String MESSAGE_TYPE_STRING = "SetResponse"; - final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "指令序号" + getSequence() + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/DataFrame.java b/src/main/java/com/casic/tube/frame/DataFrame.java deleted file mode 100644 index 97e07b8..0000000 --- a/src/main/java/com/casic/tube/frame/DataFrame.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import com.casic.dao.model.DataTubeOther; - -import java.util.List; - -public class DataFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "02"; - final String MESSAGE_TYPE_STRING = "Data/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "数据消息/管盯"; - - public List dataItemList; - - public List toDataModelList() { - return null; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append(";"); - builder.append("上报时间:").append(getUptime()).append(";"); - for (DataItem dataItem : dataItemList) { - builder.append("["); - builder.append(dataItem); - builder.append("],"); - } - builder.deleteCharAt(builder.length() - 1); - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/DataItem.java b/src/main/java/com/casic/tube/frame/DataItem.java deleted file mode 100644 index 4e9aceb..0000000 --- a/src/main/java/com/casic/tube/frame/DataItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class DataItem { -} diff --git a/src/main/java/com/casic/tube/frame/EventFrame.java b/src/main/java/com/casic/tube/frame/EventFrame.java deleted file mode 100644 index ea800b4..0000000 --- a/src/main/java/com/casic/tube/frame/EventFrame.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -import java.util.List; - -public class EventFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "01"; - final String MESSAGE_TYPE_STRING = "Event/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "事件消息/管盯"; - - public List eventItemList; - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append("; "); - builder.append("上报时间:").append(getUptime()).append("; "); - for (EventItem eventItem : eventItemList) { - builder.append("["); - builder.append(eventItem); - builder.append("],"); - } - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/EventItem.java b/src/main/java/com/casic/tube/frame/EventItem.java deleted file mode 100644 index a1245bf..0000000 --- a/src/main/java/com/casic/tube/frame/EventItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class EventItem { -} diff --git a/src/main/java/com/casic/tube/frame/HeartFrame.java b/src/main/java/com/casic/tube/frame/HeartFrame.java deleted file mode 100644 index af7e7a6..0000000 --- a/src/main/java/com/casic/tube/frame/HeartFrame.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; - -@Data -public class HeartFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "00"; - final String MESSAGE_TYPE_STRING = "OnlineRequest"; - final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/IMEIFrame.java b/src/main/java/com/casic/tube/frame/IMEIFrame.java deleted file mode 100644 index 9420620..0000000 --- a/src/main/java/com/casic/tube/frame/IMEIFrame.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; - -@Data -public class IMEIFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "05"; - final String MESSAGE_TYPE_STRING = "StartupRequest"; - final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; - - String imei; - String iccid; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "IMEI:" + imei + ";" + - "ICCID:" + iccid + - "}"; - } - - @Override - public void parseMessageBody() { - imei = getMessageBody().getString("IMEI"); - iccid = getMessageBody().getString("ICCID"); - } -} diff --git a/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java b/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java index 50e8a2b..47bf4d6 100644 --- a/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java @@ -3,11 +3,12 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.casic.dao.model.DataTubeOther; -import com.casic.tube.frame.DataFrame; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -19,7 +20,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override @@ -43,8 +45,8 @@ } @Override - public List toDataModelList() { - List dataList = new ArrayList<>(); + public List toDataModelList() { + List dataList = new ArrayList<>(); for (DataItem dataItem : dataItemList) { DataTubeOther data = new DataTubeOther(); diff --git a/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java b/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java index 8d09b10..75e94c7 100644 --- a/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.brs; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java b/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java index 9026b4c..2e5c145 100644 --- a/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java @@ -2,14 +2,11 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.casic.common.CasicFrame; -import com.casic.tube.frame.EventFrame; -import com.casic.tube.frame.EventItem; +import com.casic.common.general.EventFrame; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; -import java.util.List; @Data @Slf4j @@ -17,7 +14,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override diff --git a/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java b/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java index 6c8146c..1792320 100644 --- a/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.brs; -import com.casic.tube.frame.EventItem; +import com.casic.common.general.EventItem; import lombok.Data; @Data diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java new file mode 100644 index 0000000..95d2bd4 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java @@ -0,0 +1,8 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.DataMonitorPipeOther; + +public interface IDataSentinelOtherService extends IService { + +} diff --git a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java index d6b1200..0290829 100644 --- a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java +++ b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java @@ -1,7 +1,6 @@ package com.casic.dao.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.dao.model.DataTubeOther; import com.casic.dao.model.DeviceWellView; public interface IDeviceWellViewService extends IService { diff --git a/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java new file mode 100644 index 0000000..be34f77 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java @@ -0,0 +1,16 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.BusDeviceMapper; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import org.springframework.stereotype.Service; + +@Service +public class BusDeviceServiceImpl extends ServiceImpl implements IBusDeviceService { + + @Override + public BusDevice getDeviceByCode(String devCode) { + return baseMapper.getOneByDevCode(devCode); + } +} diff --git a/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java new file mode 100644 index 0000000..0db2007 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java @@ -0,0 +1,11 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.DataSentinelOtherMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.service.IDataSentinelOtherService; +import org.springframework.stereotype.Service; + +@Service +public class DataSentinelOtherServiceImpl extends ServiceImpl implements IDataSentinelOtherService { +} diff --git a/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java new file mode 100644 index 0000000..d8c5ef2 --- /dev/null +++ b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java @@ -0,0 +1,111 @@ +package com.casic.protocol; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.CasicProtocol; +import org.springframework.stereotype.Component; + +@Component +public class CasicTubeProtocolImpl implements CasicProtocol { + @Override + public boolean checkFrame(String frame) { + boolean valid = checkFrameHeaderAndTail(frame); + if (valid) { + valid = checkFrameLength(frame); + } + + return valid; + } + + private boolean checkFrameHeaderAndTail(String frame) { + return (frame.substring(0, 2).equalsIgnoreCase("AA")) && + (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); + } + + private boolean checkFrameLength(String frame) { + String lengthStr = frame.substring(4, 7); + int length = Integer.parseInt(lengthStr); + + return frame.length() == length + 9; + } + + @Override + public String getDeviceType(String frame) { + return frame.substring(7, 9); + } + + @Override + public String getDeviceId(String frame) { + return frame.substring(9, 21); + } + + @Override + public String getManufacturerCode(String frame) { + return frame.substring(11, 13); + } + + @Override + public String getMessageType(String frame) { + return frame.substring(21, 23); + } + + @Override + public String getMessageSequence(String frame) { + return frame.substring(23, 25); + } + + @Override + public String getMessageBody(String frame) { + return frame.substring(26, frame.length() - 16); + } + + @Override + public JSONObject parseMessageBody(String messageBody) { + return JSONObject.parseObject(messageBody); + } + + @Override + public String getUptime(String frame) { + return frame.substring(frame.length() - 16, frame.length() - 2); + } + + @Override + public String buildFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append(frame.getMessageBody().toJSONString()); + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } + + @Override + public String buildReplyFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append("00"); // 消息响应类消息 消息体为00 + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/senitnel/controller/SentinelDataController.java b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java new file mode 100644 index 0000000..633c072 --- /dev/null +++ b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java @@ -0,0 +1,120 @@ +package com.casic.senitnel.controller; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.general.ConfigFrame; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import com.casic.senitnel.service.ISentinelFrameService; +import com.casic.util.aep.AepCommandSend; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Base64; +import java.util.Map; + +@Slf4j +@RestController +public class SentinelDataController { + + @Resource + private ISentinelFrameService frameService; + + @Resource + private IBusDeviceService deviceService; + + @RequestMapping("/sentinel/data/recv") + public Object dataRecv(@RequestBody Map map) { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + + JSONObject recvObj = (JSONObject) JSONObject.toJSON(map); + if (recvObj.containsKey("payload")) { + JSONObject payload = recvObj.getJSONObject("payload"); + String value = payload.getString("APPdata"); + + if (value.isEmpty()) { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } else { + byte[] baseBytes = Base64.getDecoder().decode(value); + String frameStr = new String(baseBytes); + + // 根据协议进行解析 + CasicFrame frame = frameService.dataParse(frameStr); + + if (frame != null) { + // 回复响应 + String replyFrameStr = frameService.replyMessage(frame.getDeviceCode(), frame.getSequence()); + + // 从数据库中获取master-api-key 回复响应消息 + BusDevice device = deviceService.getDeviceByCode(frame.getDeviceCode()); + if (device != null && StringUtils.isNotBlank(device.getMasterApiKey())) { + String masterApiKey = device.getMasterApiKey(); + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + + try { + int code = aepCommandSend.handleAndReply(replyFrameStr); + } catch (Exception ex) { + log.error("向设备回复响应异常:{}", ex.getMessage()); + } + } + + // 存库 + frameService.afterAction(frame); + } + + retObj.put("code", 200); + retObj.put("success", true); + } + } else { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } + + return retObj; + } + + @RequestMapping("/sentinel/config/send") + public Object configSend(@RequestBody Map map) throws Exception { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + CasicFrame cmdFrame = new ConfigFrame(); + cmdFrame.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + cmdFrame.setDeviceCode((String) map.get("devCode")); + cmdFrame.setSequence("01"); + cmdFrame.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + JSONObject messageBody = new JSONObject(); + messageBody.put("datas", map.get("cmdList")); + cmdFrame.setMessageBody(messageBody); + + String frameStr = frameService.doBuildCommand(cmdFrame); + + // TODO-LIST + // 这三个参数根据设备编号从数据库中取 + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + String masterApiKey = (String) map.get("masterApiKey"); + + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + int code = aepCommandSend.handleAndReply(frameStr); + + retObj.put("code", 200); + retObj.put("success", true); + retObj.put("AEPRetCode", code); + return retObj; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java new file mode 100644 index 0000000..368af03 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java @@ -0,0 +1,82 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; +import com.casic.dao.model.DataMonitorPipeOther; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class DataFrameNCX extends DataFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + dataItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + DataItemNCX dataItem = new DataItemNCX(); + + dataItem.setLenL(dataObj.getString("LENGL")); + dataItem.setLenR(dataObj.getString("LENGR")); + dataItem.setBat(dataObj.getString("BAT")); + dataItem.setCh4L(dataObj.getString("CH4L")); + dataItem.setCh4R(dataObj.getString("CH4R")); + dataItem.setSlope(dataObj.getString("SLOPING")); + dataItem.setDestroy(dataObj.getString("DESTROY")); + dataItem.setLeak(dataObj.getString("LEAK")); + dataItem.setDiscL(dataObj.getString("DISCL")); + dataItem.setDiscR(dataObj.getString("DISCR")); + dataItem.setVibL(dataObj.getString("VIBL")); + dataItem.setVibR(dataObj.getString("VIBR")); + dataItem.setTime(dataObj.getString("UPTIME")); + + dataItemList.add(dataItem); + } + } + + @Override + public List toDataModelList() { + List dataList = new ArrayList<>(); + for (DataItem dataItem : dataItemList) { + DataMonitorPipeOther data = new DataMonitorPipeOther(); + + data.setDevcode(getDeviceCode()); + data.setLeftLength(((DataItemNCX)dataItem).getLenL()); + data.setRightLength(((DataItemNCX)dataItem).getLenR()); + data.setLeftGas(((DataItemNCX)dataItem).getCh4L()); + data.setRightGas(((DataItemNCX)dataItem).getCh4R()); + data.setVbat(((DataItemNCX)dataItem).getBat()); + data.setPipeInclineAlarm(((DataItemNCX)dataItem).getSlope()); + data.setPipeBreakAlarm(((DataItemNCX)dataItem).getDestroy()); + data.setGasAlarm(((DataItemNCX)dataItem).getLeak()); + data.setLeftOfflineAlarm(((DataItemNCX)dataItem).getDiscL()); + data.setRightOfflineAlarm(((DataItemNCX)dataItem).getDiscR()); + data.setLeftVibrateAlarm(((DataItemNCX)dataItem).getVibL()); + data.setRightVibrateAlarm(((DataItemNCX)dataItem).getVibR()); + data.setUptime(LocalDateTime.parse(((DataItemNCX)dataItem).getTime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 采集时间 + data.setLogtime(LocalDateTime.parse(getUptime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 上报时间 + + dataList.add(data); + } + + return dataList; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java new file mode 100644 index 0000000..372ac73 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java @@ -0,0 +1,31 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.DataItem; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class DataItemNCX extends DataItem { + String lenL; // 左侧指示带长度 + String lenR; // 右侧指示带长度 + String ch4L; // 左侧甲烷浓度值 + String ch4R; // 右侧甲烷浓度值 + String bat; // 电池电压 + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String spare; // 备用 + String time; // 采集时间 + + @Override + public String toString() { + return "气体浓度值:" + "(" + ch4L + "," + ch4R + ")" + "%LEL;" + + "电池电压值:" + bat + "v;" + + "采样时间:" + time; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java new file mode 100644 index 0000000..b3bbcf4 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java @@ -0,0 +1,43 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.EventFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class EventFrameNCX extends EventFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + eventItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + EventItemNCX eventItem = new EventItemNCX(); + + eventItem.setSlope(dataObj.getString("SLOPING")); + eventItem.setDestroy(dataObj.getString("DESTROY")); + eventItem.setLeak(dataObj.getString("LEAK")); + eventItem.setDiscL(dataObj.getString("DISCL")); + eventItem.setDiscR(dataObj.getString("DISCR")); + eventItem.setVibL(dataObj.getString("VIBL")); + eventItem.setVibR(dataObj.getString("VIBR")); + eventItem.setTime(dataObj.getString("UPTIME")); + + eventItemList.add(eventItem); + } + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java new file mode 100644 index 0000000..1a560d0 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java @@ -0,0 +1,49 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.EventItem; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.commons.lang3.StringUtils; + +@EqualsAndHashCode(callSuper = true) +@Data +public class EventItemNCX extends EventItem { + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String time; // 采集时间 + + @Override + public String toString() { + String str = ""; + if (StringUtils.isNotBlank(slope) && slope.equalsIgnoreCase("1")) { + str += "[倾斜报警]"; + } + if (StringUtils.isNotBlank(destroy) && destroy.equalsIgnoreCase("1")) { + str += "[破坏报警]"; + } + if (StringUtils.isNotBlank(leak) && leak.equalsIgnoreCase("1")) { + str += "[甲烷泄漏报警]"; + } + if (StringUtils.isNotBlank(discL) && discL.equalsIgnoreCase("1")) { + str += "[左侧断线报警]"; + } + if (StringUtils.isNotBlank(discR) && discR.equalsIgnoreCase("1")) { + str += "[右侧断线报警]"; + } + if (StringUtils.isNotBlank(vibL) && vibL.equalsIgnoreCase("1")) { + str += "[左侧振动报警]"; + } + if (StringUtils.isNotBlank(vibR) && vibR.equalsIgnoreCase("1")) { + str += "[右侧振动报警]"; + } + str += "采样时间:" + time; + + return str; + + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java new file mode 100644 index 0000000..343c4d6 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java @@ -0,0 +1,37 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class InfoFrameNCX extends CasicFrame { + + String workMode; + String model; + String hwVersion; + String softVersion; + String sensorType; + + @Override + public String toString() { + return "设备编号: " + getDeviceCode() + "; " + + "设备工作模式: " + workMode + " ; " + + "设备型号: " + model + " ; " + + "版本号: " + hwVersion + ", " + softVersion + "; " + + "传感器类型: " + sensorType + " ; " + + "上报时间: " + getUptime(); + } + + @Override + public void parseMessageBody() { + workMode = getMessageBody().getString("WORKMODE"); + model = getMessageBody().getString("MODEL"); + hwVersion = getMessageBody().getString("HWVERSION"); + softVersion = getMessageBody().getString("SOFTVERSION"); + sensorType = getMessageBody().getString("SENSORTYPE"); + } +} diff --git a/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java new file mode 100644 index 0000000..e76fc86 --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java @@ -0,0 +1,14 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; + +public interface ISentinelFrameService { + + CasicFrame dataParse(String frame); + + String replyMessage(String deviceCode, String sequence); + + String doBuildCommand(CasicFrame cmd); + + void afterAction(CasicFrame frame); +} diff --git a/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java new file mode 100644 index 0000000..803ff0e --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java @@ -0,0 +1,109 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; +import com.casic.common.CasicFrameBuildFactory; +import com.casic.common.CasicProtocol; +import com.casic.common.general.DataFrame; +import com.casic.common.general.EventFrame; +import com.casic.common.general.ReplyFrame; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.model.DeviceWellView; +import com.casic.dao.service.IDataSentinelOtherService; +import com.casic.dao.service.IDeviceWellViewService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + + +@Service +@Slf4j +public class SentinelFrameServiceImpl implements ISentinelFrameService { + + @Resource + private CasicProtocol protocol; + + @Resource + IDataSentinelOtherService sentinelDataService; + + @Resource + IDeviceWellViewService deviceService; + + public CasicFrame dataParse(String frame) { + // 1. 判断帧结构 + boolean frameValid = protocol.checkFrame(frame); + if (frameValid) { + // 2. 获取帧结构中的关键字段信息 + String deviceId = protocol.getDeviceId(frame); + String deviceType = protocol.getDeviceType(frame); + String messageType = protocol.getMessageType(frame); + String messageBody = protocol.getMessageBody(frame).toUpperCase(); + String uptime = protocol.getUptime(frame); + String sequence = protocol.getMessageSequence(frame); + + String manufacturerCode = protocol.getManufacturerCode(frame); + CasicFrame sentinelFrame = CasicFrameBuildFactory.buildCasicFrame(messageType, manufacturerCode, deviceType); + + if (sentinelFrame != null) { + sentinelFrame.setDeviceCode(deviceId); + sentinelFrame.setUptime(uptime); + sentinelFrame.setMessageType(messageType); + sentinelFrame.setSequence(sequence); + + // 心跳类的消息不解析MessageBody + if (!sentinelFrame.getMessageType().equals("00")) { + sentinelFrame.setMessageBody(protocol.parseMessageBody(messageBody)); + sentinelFrame.parseMessageBody(); + } + + log.info("收到设备消息:{}", sentinelFrame); + return sentinelFrame; + } + } else { + log.error("消息帧解析异常"); + } + + return null; + } + + @Override + public String replyMessage(String deviceCode, String sequence) { + CasicFrame reply = new ReplyFrame(); + reply.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + reply.setDeviceCode(deviceCode); + reply.setSequence(sequence); + reply.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + return protocol.buildReplyFrameStr(reply); + } + + @Override + public String doBuildCommand(CasicFrame cmd) { + return protocol.buildFrameStr(cmd); + } + + @Override + public void afterAction(CasicFrame frame) { + // 数据消息帧 进行存库操作 + if (frame instanceof DataFrame) { + String devCode = frame.getDeviceCode(); + DeviceWellView devWellView = deviceService.getDeviceWellViewByDevCode(devCode); + String wellCode = ""; + if (devWellView != null) { + wellCode = devWellView.getWellCode(); + } + List dataList = ((DataFrame) frame).toDataModelList(); + if (dataList != null) { + for (Serializable item : dataList) { + DataMonitorPipeOther data = (DataMonitorPipeOther) item; + data.setWellCode(wellCode); + sentinelDataService.save(data); + } + } + } + } +} diff --git a/src/main/java/com/casic/tube/controller/TubeDataController.java b/src/main/java/com/casic/tube/controller/TubeDataController.java index 61486c5..4965449 100644 --- a/src/main/java/com/casic/tube/controller/TubeDataController.java +++ b/src/main/java/com/casic/tube/controller/TubeDataController.java @@ -2,8 +2,8 @@ import com.alibaba.fastjson.JSONObject; import com.casic.common.CasicFrame; -import com.casic.tube.frame.ConfigFrame; -import com.casic.tube.service.ITubeDataService; +import com.casic.common.general.ConfigFrame; +import com.casic.tube.service.ITubeFrameService; import com.casic.util.aep.AepCommandSend; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestBody; @@ -21,7 +21,7 @@ public class TubeDataController { @Resource - private ITubeDataService tubeDataService; + private ITubeFrameService frameService; @RequestMapping("/tube/data/recv") public Object dataRecv(@RequestBody Map map) { @@ -42,10 +42,10 @@ String frameStr = new String(baseBytes); // 根据协议进行解析 - CasicFrame frame = tubeDataService.dataParse(frameStr); + CasicFrame frame = frameService.dataParse(frameStr); // 存库 - tubeDataService.afterAction(frame); + frameService.afterAction(frame); retObj.put("code", 200); retObj.put("success", true); @@ -74,7 +74,7 @@ messageBody.put("datas", map.get("cmdList")); cmdFrame.setMessageBody(messageBody); - String frameStr = tubeDataService.doBuildCommand(cmdFrame); + String frameStr = frameService.doBuildCommand(cmdFrame); // TODO-LIST // 这三个参数根据设备编号从数据库中取 diff --git a/src/main/java/com/casic/tube/frame/ConfigFrame.java b/src/main/java/com/casic/tube/frame/ConfigFrame.java deleted file mode 100644 index 883dad6..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigFrame.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigFrame extends CasicFrame { - - public ConfigFrame() { - setSequence("01"); // 默认序号 - setControl("1"); // 默认为不需要分包 - setMessageType("52"); // 消息大类 52 = SetRequest - } -} diff --git a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java b/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java deleted file mode 100644 index a419145..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigResponseFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "03"; - final String MESSAGE_TYPE_STRING = "SetResponse"; - final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "指令序号" + getSequence() + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/DataFrame.java b/src/main/java/com/casic/tube/frame/DataFrame.java deleted file mode 100644 index 97e07b8..0000000 --- a/src/main/java/com/casic/tube/frame/DataFrame.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import com.casic.dao.model.DataTubeOther; - -import java.util.List; - -public class DataFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "02"; - final String MESSAGE_TYPE_STRING = "Data/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "数据消息/管盯"; - - public List dataItemList; - - public List toDataModelList() { - return null; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append(";"); - builder.append("上报时间:").append(getUptime()).append(";"); - for (DataItem dataItem : dataItemList) { - builder.append("["); - builder.append(dataItem); - builder.append("],"); - } - builder.deleteCharAt(builder.length() - 1); - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/DataItem.java b/src/main/java/com/casic/tube/frame/DataItem.java deleted file mode 100644 index 4e9aceb..0000000 --- a/src/main/java/com/casic/tube/frame/DataItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class DataItem { -} diff --git a/src/main/java/com/casic/tube/frame/EventFrame.java b/src/main/java/com/casic/tube/frame/EventFrame.java deleted file mode 100644 index ea800b4..0000000 --- a/src/main/java/com/casic/tube/frame/EventFrame.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -import java.util.List; - -public class EventFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "01"; - final String MESSAGE_TYPE_STRING = "Event/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "事件消息/管盯"; - - public List eventItemList; - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append("; "); - builder.append("上报时间:").append(getUptime()).append("; "); - for (EventItem eventItem : eventItemList) { - builder.append("["); - builder.append(eventItem); - builder.append("],"); - } - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/EventItem.java b/src/main/java/com/casic/tube/frame/EventItem.java deleted file mode 100644 index a1245bf..0000000 --- a/src/main/java/com/casic/tube/frame/EventItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class EventItem { -} diff --git a/src/main/java/com/casic/tube/frame/HeartFrame.java b/src/main/java/com/casic/tube/frame/HeartFrame.java deleted file mode 100644 index af7e7a6..0000000 --- a/src/main/java/com/casic/tube/frame/HeartFrame.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; - -@Data -public class HeartFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "00"; - final String MESSAGE_TYPE_STRING = "OnlineRequest"; - final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/IMEIFrame.java b/src/main/java/com/casic/tube/frame/IMEIFrame.java deleted file mode 100644 index 9420620..0000000 --- a/src/main/java/com/casic/tube/frame/IMEIFrame.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; - -@Data -public class IMEIFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "05"; - final String MESSAGE_TYPE_STRING = "StartupRequest"; - final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; - - String imei; - String iccid; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "IMEI:" + imei + ";" + - "ICCID:" + iccid + - "}"; - } - - @Override - public void parseMessageBody() { - imei = getMessageBody().getString("IMEI"); - iccid = getMessageBody().getString("ICCID"); - } -} diff --git a/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java b/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java index 50e8a2b..47bf4d6 100644 --- a/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java @@ -3,11 +3,12 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.casic.dao.model.DataTubeOther; -import com.casic.tube.frame.DataFrame; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -19,7 +20,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override @@ -43,8 +45,8 @@ } @Override - public List toDataModelList() { - List dataList = new ArrayList<>(); + public List toDataModelList() { + List dataList = new ArrayList<>(); for (DataItem dataItem : dataItemList) { DataTubeOther data = new DataTubeOther(); diff --git a/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java b/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java index 8d09b10..75e94c7 100644 --- a/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.brs; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java b/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java index 9026b4c..2e5c145 100644 --- a/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java @@ -2,14 +2,11 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.casic.common.CasicFrame; -import com.casic.tube.frame.EventFrame; -import com.casic.tube.frame.EventItem; +import com.casic.common.general.EventFrame; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; -import java.util.List; @Data @Slf4j @@ -17,7 +14,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override diff --git a/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java b/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java index 6c8146c..1792320 100644 --- a/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.brs; -import com.casic.tube.frame.EventItem; +import com.casic.common.general.EventItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java b/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java index e6e541c..b05b358 100644 --- a/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java @@ -3,11 +3,12 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.casic.dao.model.DataTubeOther; -import com.casic.tube.frame.DataFrame; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -19,7 +20,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override @@ -43,8 +45,8 @@ } @Override - public List toDataModelList() { - List dataList = new ArrayList<>(); + public List toDataModelList() { + List dataList = new ArrayList<>(); for (DataItem dataItem : dataItemList) { DataTubeOther data = new DataTubeOther(); diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java new file mode 100644 index 0000000..95d2bd4 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java @@ -0,0 +1,8 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.DataMonitorPipeOther; + +public interface IDataSentinelOtherService extends IService { + +} diff --git a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java index d6b1200..0290829 100644 --- a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java +++ b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java @@ -1,7 +1,6 @@ package com.casic.dao.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.dao.model.DataTubeOther; import com.casic.dao.model.DeviceWellView; public interface IDeviceWellViewService extends IService { diff --git a/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java new file mode 100644 index 0000000..be34f77 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java @@ -0,0 +1,16 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.BusDeviceMapper; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import org.springframework.stereotype.Service; + +@Service +public class BusDeviceServiceImpl extends ServiceImpl implements IBusDeviceService { + + @Override + public BusDevice getDeviceByCode(String devCode) { + return baseMapper.getOneByDevCode(devCode); + } +} diff --git a/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java new file mode 100644 index 0000000..0db2007 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java @@ -0,0 +1,11 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.DataSentinelOtherMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.service.IDataSentinelOtherService; +import org.springframework.stereotype.Service; + +@Service +public class DataSentinelOtherServiceImpl extends ServiceImpl implements IDataSentinelOtherService { +} diff --git a/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java new file mode 100644 index 0000000..d8c5ef2 --- /dev/null +++ b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java @@ -0,0 +1,111 @@ +package com.casic.protocol; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.CasicProtocol; +import org.springframework.stereotype.Component; + +@Component +public class CasicTubeProtocolImpl implements CasicProtocol { + @Override + public boolean checkFrame(String frame) { + boolean valid = checkFrameHeaderAndTail(frame); + if (valid) { + valid = checkFrameLength(frame); + } + + return valid; + } + + private boolean checkFrameHeaderAndTail(String frame) { + return (frame.substring(0, 2).equalsIgnoreCase("AA")) && + (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); + } + + private boolean checkFrameLength(String frame) { + String lengthStr = frame.substring(4, 7); + int length = Integer.parseInt(lengthStr); + + return frame.length() == length + 9; + } + + @Override + public String getDeviceType(String frame) { + return frame.substring(7, 9); + } + + @Override + public String getDeviceId(String frame) { + return frame.substring(9, 21); + } + + @Override + public String getManufacturerCode(String frame) { + return frame.substring(11, 13); + } + + @Override + public String getMessageType(String frame) { + return frame.substring(21, 23); + } + + @Override + public String getMessageSequence(String frame) { + return frame.substring(23, 25); + } + + @Override + public String getMessageBody(String frame) { + return frame.substring(26, frame.length() - 16); + } + + @Override + public JSONObject parseMessageBody(String messageBody) { + return JSONObject.parseObject(messageBody); + } + + @Override + public String getUptime(String frame) { + return frame.substring(frame.length() - 16, frame.length() - 2); + } + + @Override + public String buildFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append(frame.getMessageBody().toJSONString()); + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } + + @Override + public String buildReplyFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append("00"); // 消息响应类消息 消息体为00 + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/senitnel/controller/SentinelDataController.java b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java new file mode 100644 index 0000000..633c072 --- /dev/null +++ b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java @@ -0,0 +1,120 @@ +package com.casic.senitnel.controller; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.general.ConfigFrame; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import com.casic.senitnel.service.ISentinelFrameService; +import com.casic.util.aep.AepCommandSend; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Base64; +import java.util.Map; + +@Slf4j +@RestController +public class SentinelDataController { + + @Resource + private ISentinelFrameService frameService; + + @Resource + private IBusDeviceService deviceService; + + @RequestMapping("/sentinel/data/recv") + public Object dataRecv(@RequestBody Map map) { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + + JSONObject recvObj = (JSONObject) JSONObject.toJSON(map); + if (recvObj.containsKey("payload")) { + JSONObject payload = recvObj.getJSONObject("payload"); + String value = payload.getString("APPdata"); + + if (value.isEmpty()) { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } else { + byte[] baseBytes = Base64.getDecoder().decode(value); + String frameStr = new String(baseBytes); + + // 根据协议进行解析 + CasicFrame frame = frameService.dataParse(frameStr); + + if (frame != null) { + // 回复响应 + String replyFrameStr = frameService.replyMessage(frame.getDeviceCode(), frame.getSequence()); + + // 从数据库中获取master-api-key 回复响应消息 + BusDevice device = deviceService.getDeviceByCode(frame.getDeviceCode()); + if (device != null && StringUtils.isNotBlank(device.getMasterApiKey())) { + String masterApiKey = device.getMasterApiKey(); + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + + try { + int code = aepCommandSend.handleAndReply(replyFrameStr); + } catch (Exception ex) { + log.error("向设备回复响应异常:{}", ex.getMessage()); + } + } + + // 存库 + frameService.afterAction(frame); + } + + retObj.put("code", 200); + retObj.put("success", true); + } + } else { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } + + return retObj; + } + + @RequestMapping("/sentinel/config/send") + public Object configSend(@RequestBody Map map) throws Exception { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + CasicFrame cmdFrame = new ConfigFrame(); + cmdFrame.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + cmdFrame.setDeviceCode((String) map.get("devCode")); + cmdFrame.setSequence("01"); + cmdFrame.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + JSONObject messageBody = new JSONObject(); + messageBody.put("datas", map.get("cmdList")); + cmdFrame.setMessageBody(messageBody); + + String frameStr = frameService.doBuildCommand(cmdFrame); + + // TODO-LIST + // 这三个参数根据设备编号从数据库中取 + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + String masterApiKey = (String) map.get("masterApiKey"); + + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + int code = aepCommandSend.handleAndReply(frameStr); + + retObj.put("code", 200); + retObj.put("success", true); + retObj.put("AEPRetCode", code); + return retObj; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java new file mode 100644 index 0000000..368af03 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java @@ -0,0 +1,82 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; +import com.casic.dao.model.DataMonitorPipeOther; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class DataFrameNCX extends DataFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + dataItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + DataItemNCX dataItem = new DataItemNCX(); + + dataItem.setLenL(dataObj.getString("LENGL")); + dataItem.setLenR(dataObj.getString("LENGR")); + dataItem.setBat(dataObj.getString("BAT")); + dataItem.setCh4L(dataObj.getString("CH4L")); + dataItem.setCh4R(dataObj.getString("CH4R")); + dataItem.setSlope(dataObj.getString("SLOPING")); + dataItem.setDestroy(dataObj.getString("DESTROY")); + dataItem.setLeak(dataObj.getString("LEAK")); + dataItem.setDiscL(dataObj.getString("DISCL")); + dataItem.setDiscR(dataObj.getString("DISCR")); + dataItem.setVibL(dataObj.getString("VIBL")); + dataItem.setVibR(dataObj.getString("VIBR")); + dataItem.setTime(dataObj.getString("UPTIME")); + + dataItemList.add(dataItem); + } + } + + @Override + public List toDataModelList() { + List dataList = new ArrayList<>(); + for (DataItem dataItem : dataItemList) { + DataMonitorPipeOther data = new DataMonitorPipeOther(); + + data.setDevcode(getDeviceCode()); + data.setLeftLength(((DataItemNCX)dataItem).getLenL()); + data.setRightLength(((DataItemNCX)dataItem).getLenR()); + data.setLeftGas(((DataItemNCX)dataItem).getCh4L()); + data.setRightGas(((DataItemNCX)dataItem).getCh4R()); + data.setVbat(((DataItemNCX)dataItem).getBat()); + data.setPipeInclineAlarm(((DataItemNCX)dataItem).getSlope()); + data.setPipeBreakAlarm(((DataItemNCX)dataItem).getDestroy()); + data.setGasAlarm(((DataItemNCX)dataItem).getLeak()); + data.setLeftOfflineAlarm(((DataItemNCX)dataItem).getDiscL()); + data.setRightOfflineAlarm(((DataItemNCX)dataItem).getDiscR()); + data.setLeftVibrateAlarm(((DataItemNCX)dataItem).getVibL()); + data.setRightVibrateAlarm(((DataItemNCX)dataItem).getVibR()); + data.setUptime(LocalDateTime.parse(((DataItemNCX)dataItem).getTime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 采集时间 + data.setLogtime(LocalDateTime.parse(getUptime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 上报时间 + + dataList.add(data); + } + + return dataList; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java new file mode 100644 index 0000000..372ac73 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java @@ -0,0 +1,31 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.DataItem; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class DataItemNCX extends DataItem { + String lenL; // 左侧指示带长度 + String lenR; // 右侧指示带长度 + String ch4L; // 左侧甲烷浓度值 + String ch4R; // 右侧甲烷浓度值 + String bat; // 电池电压 + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String spare; // 备用 + String time; // 采集时间 + + @Override + public String toString() { + return "气体浓度值:" + "(" + ch4L + "," + ch4R + ")" + "%LEL;" + + "电池电压值:" + bat + "v;" + + "采样时间:" + time; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java new file mode 100644 index 0000000..b3bbcf4 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java @@ -0,0 +1,43 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.EventFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class EventFrameNCX extends EventFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + eventItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + EventItemNCX eventItem = new EventItemNCX(); + + eventItem.setSlope(dataObj.getString("SLOPING")); + eventItem.setDestroy(dataObj.getString("DESTROY")); + eventItem.setLeak(dataObj.getString("LEAK")); + eventItem.setDiscL(dataObj.getString("DISCL")); + eventItem.setDiscR(dataObj.getString("DISCR")); + eventItem.setVibL(dataObj.getString("VIBL")); + eventItem.setVibR(dataObj.getString("VIBR")); + eventItem.setTime(dataObj.getString("UPTIME")); + + eventItemList.add(eventItem); + } + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java new file mode 100644 index 0000000..1a560d0 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java @@ -0,0 +1,49 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.EventItem; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.commons.lang3.StringUtils; + +@EqualsAndHashCode(callSuper = true) +@Data +public class EventItemNCX extends EventItem { + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String time; // 采集时间 + + @Override + public String toString() { + String str = ""; + if (StringUtils.isNotBlank(slope) && slope.equalsIgnoreCase("1")) { + str += "[倾斜报警]"; + } + if (StringUtils.isNotBlank(destroy) && destroy.equalsIgnoreCase("1")) { + str += "[破坏报警]"; + } + if (StringUtils.isNotBlank(leak) && leak.equalsIgnoreCase("1")) { + str += "[甲烷泄漏报警]"; + } + if (StringUtils.isNotBlank(discL) && discL.equalsIgnoreCase("1")) { + str += "[左侧断线报警]"; + } + if (StringUtils.isNotBlank(discR) && discR.equalsIgnoreCase("1")) { + str += "[右侧断线报警]"; + } + if (StringUtils.isNotBlank(vibL) && vibL.equalsIgnoreCase("1")) { + str += "[左侧振动报警]"; + } + if (StringUtils.isNotBlank(vibR) && vibR.equalsIgnoreCase("1")) { + str += "[右侧振动报警]"; + } + str += "采样时间:" + time; + + return str; + + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java new file mode 100644 index 0000000..343c4d6 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java @@ -0,0 +1,37 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class InfoFrameNCX extends CasicFrame { + + String workMode; + String model; + String hwVersion; + String softVersion; + String sensorType; + + @Override + public String toString() { + return "设备编号: " + getDeviceCode() + "; " + + "设备工作模式: " + workMode + " ; " + + "设备型号: " + model + " ; " + + "版本号: " + hwVersion + ", " + softVersion + "; " + + "传感器类型: " + sensorType + " ; " + + "上报时间: " + getUptime(); + } + + @Override + public void parseMessageBody() { + workMode = getMessageBody().getString("WORKMODE"); + model = getMessageBody().getString("MODEL"); + hwVersion = getMessageBody().getString("HWVERSION"); + softVersion = getMessageBody().getString("SOFTVERSION"); + sensorType = getMessageBody().getString("SENSORTYPE"); + } +} diff --git a/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java new file mode 100644 index 0000000..e76fc86 --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java @@ -0,0 +1,14 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; + +public interface ISentinelFrameService { + + CasicFrame dataParse(String frame); + + String replyMessage(String deviceCode, String sequence); + + String doBuildCommand(CasicFrame cmd); + + void afterAction(CasicFrame frame); +} diff --git a/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java new file mode 100644 index 0000000..803ff0e --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java @@ -0,0 +1,109 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; +import com.casic.common.CasicFrameBuildFactory; +import com.casic.common.CasicProtocol; +import com.casic.common.general.DataFrame; +import com.casic.common.general.EventFrame; +import com.casic.common.general.ReplyFrame; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.model.DeviceWellView; +import com.casic.dao.service.IDataSentinelOtherService; +import com.casic.dao.service.IDeviceWellViewService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + + +@Service +@Slf4j +public class SentinelFrameServiceImpl implements ISentinelFrameService { + + @Resource + private CasicProtocol protocol; + + @Resource + IDataSentinelOtherService sentinelDataService; + + @Resource + IDeviceWellViewService deviceService; + + public CasicFrame dataParse(String frame) { + // 1. 判断帧结构 + boolean frameValid = protocol.checkFrame(frame); + if (frameValid) { + // 2. 获取帧结构中的关键字段信息 + String deviceId = protocol.getDeviceId(frame); + String deviceType = protocol.getDeviceType(frame); + String messageType = protocol.getMessageType(frame); + String messageBody = protocol.getMessageBody(frame).toUpperCase(); + String uptime = protocol.getUptime(frame); + String sequence = protocol.getMessageSequence(frame); + + String manufacturerCode = protocol.getManufacturerCode(frame); + CasicFrame sentinelFrame = CasicFrameBuildFactory.buildCasicFrame(messageType, manufacturerCode, deviceType); + + if (sentinelFrame != null) { + sentinelFrame.setDeviceCode(deviceId); + sentinelFrame.setUptime(uptime); + sentinelFrame.setMessageType(messageType); + sentinelFrame.setSequence(sequence); + + // 心跳类的消息不解析MessageBody + if (!sentinelFrame.getMessageType().equals("00")) { + sentinelFrame.setMessageBody(protocol.parseMessageBody(messageBody)); + sentinelFrame.parseMessageBody(); + } + + log.info("收到设备消息:{}", sentinelFrame); + return sentinelFrame; + } + } else { + log.error("消息帧解析异常"); + } + + return null; + } + + @Override + public String replyMessage(String deviceCode, String sequence) { + CasicFrame reply = new ReplyFrame(); + reply.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + reply.setDeviceCode(deviceCode); + reply.setSequence(sequence); + reply.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + return protocol.buildReplyFrameStr(reply); + } + + @Override + public String doBuildCommand(CasicFrame cmd) { + return protocol.buildFrameStr(cmd); + } + + @Override + public void afterAction(CasicFrame frame) { + // 数据消息帧 进行存库操作 + if (frame instanceof DataFrame) { + String devCode = frame.getDeviceCode(); + DeviceWellView devWellView = deviceService.getDeviceWellViewByDevCode(devCode); + String wellCode = ""; + if (devWellView != null) { + wellCode = devWellView.getWellCode(); + } + List dataList = ((DataFrame) frame).toDataModelList(); + if (dataList != null) { + for (Serializable item : dataList) { + DataMonitorPipeOther data = (DataMonitorPipeOther) item; + data.setWellCode(wellCode); + sentinelDataService.save(data); + } + } + } + } +} diff --git a/src/main/java/com/casic/tube/controller/TubeDataController.java b/src/main/java/com/casic/tube/controller/TubeDataController.java index 61486c5..4965449 100644 --- a/src/main/java/com/casic/tube/controller/TubeDataController.java +++ b/src/main/java/com/casic/tube/controller/TubeDataController.java @@ -2,8 +2,8 @@ import com.alibaba.fastjson.JSONObject; import com.casic.common.CasicFrame; -import com.casic.tube.frame.ConfigFrame; -import com.casic.tube.service.ITubeDataService; +import com.casic.common.general.ConfigFrame; +import com.casic.tube.service.ITubeFrameService; import com.casic.util.aep.AepCommandSend; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestBody; @@ -21,7 +21,7 @@ public class TubeDataController { @Resource - private ITubeDataService tubeDataService; + private ITubeFrameService frameService; @RequestMapping("/tube/data/recv") public Object dataRecv(@RequestBody Map map) { @@ -42,10 +42,10 @@ String frameStr = new String(baseBytes); // 根据协议进行解析 - CasicFrame frame = tubeDataService.dataParse(frameStr); + CasicFrame frame = frameService.dataParse(frameStr); // 存库 - tubeDataService.afterAction(frame); + frameService.afterAction(frame); retObj.put("code", 200); retObj.put("success", true); @@ -74,7 +74,7 @@ messageBody.put("datas", map.get("cmdList")); cmdFrame.setMessageBody(messageBody); - String frameStr = tubeDataService.doBuildCommand(cmdFrame); + String frameStr = frameService.doBuildCommand(cmdFrame); // TODO-LIST // 这三个参数根据设备编号从数据库中取 diff --git a/src/main/java/com/casic/tube/frame/ConfigFrame.java b/src/main/java/com/casic/tube/frame/ConfigFrame.java deleted file mode 100644 index 883dad6..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigFrame.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigFrame extends CasicFrame { - - public ConfigFrame() { - setSequence("01"); // 默认序号 - setControl("1"); // 默认为不需要分包 - setMessageType("52"); // 消息大类 52 = SetRequest - } -} diff --git a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java b/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java deleted file mode 100644 index a419145..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigResponseFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "03"; - final String MESSAGE_TYPE_STRING = "SetResponse"; - final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "指令序号" + getSequence() + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/DataFrame.java b/src/main/java/com/casic/tube/frame/DataFrame.java deleted file mode 100644 index 97e07b8..0000000 --- a/src/main/java/com/casic/tube/frame/DataFrame.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import com.casic.dao.model.DataTubeOther; - -import java.util.List; - -public class DataFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "02"; - final String MESSAGE_TYPE_STRING = "Data/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "数据消息/管盯"; - - public List dataItemList; - - public List toDataModelList() { - return null; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append(";"); - builder.append("上报时间:").append(getUptime()).append(";"); - for (DataItem dataItem : dataItemList) { - builder.append("["); - builder.append(dataItem); - builder.append("],"); - } - builder.deleteCharAt(builder.length() - 1); - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/DataItem.java b/src/main/java/com/casic/tube/frame/DataItem.java deleted file mode 100644 index 4e9aceb..0000000 --- a/src/main/java/com/casic/tube/frame/DataItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class DataItem { -} diff --git a/src/main/java/com/casic/tube/frame/EventFrame.java b/src/main/java/com/casic/tube/frame/EventFrame.java deleted file mode 100644 index ea800b4..0000000 --- a/src/main/java/com/casic/tube/frame/EventFrame.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -import java.util.List; - -public class EventFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "01"; - final String MESSAGE_TYPE_STRING = "Event/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "事件消息/管盯"; - - public List eventItemList; - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append("; "); - builder.append("上报时间:").append(getUptime()).append("; "); - for (EventItem eventItem : eventItemList) { - builder.append("["); - builder.append(eventItem); - builder.append("],"); - } - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/EventItem.java b/src/main/java/com/casic/tube/frame/EventItem.java deleted file mode 100644 index a1245bf..0000000 --- a/src/main/java/com/casic/tube/frame/EventItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class EventItem { -} diff --git a/src/main/java/com/casic/tube/frame/HeartFrame.java b/src/main/java/com/casic/tube/frame/HeartFrame.java deleted file mode 100644 index af7e7a6..0000000 --- a/src/main/java/com/casic/tube/frame/HeartFrame.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; - -@Data -public class HeartFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "00"; - final String MESSAGE_TYPE_STRING = "OnlineRequest"; - final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/IMEIFrame.java b/src/main/java/com/casic/tube/frame/IMEIFrame.java deleted file mode 100644 index 9420620..0000000 --- a/src/main/java/com/casic/tube/frame/IMEIFrame.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; - -@Data -public class IMEIFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "05"; - final String MESSAGE_TYPE_STRING = "StartupRequest"; - final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; - - String imei; - String iccid; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "IMEI:" + imei + ";" + - "ICCID:" + iccid + - "}"; - } - - @Override - public void parseMessageBody() { - imei = getMessageBody().getString("IMEI"); - iccid = getMessageBody().getString("ICCID"); - } -} diff --git a/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java b/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java index 50e8a2b..47bf4d6 100644 --- a/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java @@ -3,11 +3,12 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.casic.dao.model.DataTubeOther; -import com.casic.tube.frame.DataFrame; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -19,7 +20,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override @@ -43,8 +45,8 @@ } @Override - public List toDataModelList() { - List dataList = new ArrayList<>(); + public List toDataModelList() { + List dataList = new ArrayList<>(); for (DataItem dataItem : dataItemList) { DataTubeOther data = new DataTubeOther(); diff --git a/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java b/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java index 8d09b10..75e94c7 100644 --- a/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.brs; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java b/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java index 9026b4c..2e5c145 100644 --- a/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java @@ -2,14 +2,11 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.casic.common.CasicFrame; -import com.casic.tube.frame.EventFrame; -import com.casic.tube.frame.EventItem; +import com.casic.common.general.EventFrame; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; -import java.util.List; @Data @Slf4j @@ -17,7 +14,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override diff --git a/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java b/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java index 6c8146c..1792320 100644 --- a/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.brs; -import com.casic.tube.frame.EventItem; +import com.casic.common.general.EventItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java b/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java index e6e541c..b05b358 100644 --- a/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java @@ -3,11 +3,12 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.casic.dao.model.DataTubeOther; -import com.casic.tube.frame.DataFrame; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -19,7 +20,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override @@ -43,8 +45,8 @@ } @Override - public List toDataModelList() { - List dataList = new ArrayList<>(); + public List toDataModelList() { + List dataList = new ArrayList<>(); for (DataItem dataItem : dataItemList) { DataTubeOther data = new DataTubeOther(); diff --git a/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java b/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java index 0aa9bab..e875f2a 100644 --- a/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.mhk; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataItem; import lombok.Data; @Data diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java new file mode 100644 index 0000000..95d2bd4 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java @@ -0,0 +1,8 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.DataMonitorPipeOther; + +public interface IDataSentinelOtherService extends IService { + +} diff --git a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java index d6b1200..0290829 100644 --- a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java +++ b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java @@ -1,7 +1,6 @@ package com.casic.dao.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.dao.model.DataTubeOther; import com.casic.dao.model.DeviceWellView; public interface IDeviceWellViewService extends IService { diff --git a/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java new file mode 100644 index 0000000..be34f77 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java @@ -0,0 +1,16 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.BusDeviceMapper; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import org.springframework.stereotype.Service; + +@Service +public class BusDeviceServiceImpl extends ServiceImpl implements IBusDeviceService { + + @Override + public BusDevice getDeviceByCode(String devCode) { + return baseMapper.getOneByDevCode(devCode); + } +} diff --git a/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java new file mode 100644 index 0000000..0db2007 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java @@ -0,0 +1,11 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.DataSentinelOtherMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.service.IDataSentinelOtherService; +import org.springframework.stereotype.Service; + +@Service +public class DataSentinelOtherServiceImpl extends ServiceImpl implements IDataSentinelOtherService { +} diff --git a/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java new file mode 100644 index 0000000..d8c5ef2 --- /dev/null +++ b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java @@ -0,0 +1,111 @@ +package com.casic.protocol; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.CasicProtocol; +import org.springframework.stereotype.Component; + +@Component +public class CasicTubeProtocolImpl implements CasicProtocol { + @Override + public boolean checkFrame(String frame) { + boolean valid = checkFrameHeaderAndTail(frame); + if (valid) { + valid = checkFrameLength(frame); + } + + return valid; + } + + private boolean checkFrameHeaderAndTail(String frame) { + return (frame.substring(0, 2).equalsIgnoreCase("AA")) && + (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); + } + + private boolean checkFrameLength(String frame) { + String lengthStr = frame.substring(4, 7); + int length = Integer.parseInt(lengthStr); + + return frame.length() == length + 9; + } + + @Override + public String getDeviceType(String frame) { + return frame.substring(7, 9); + } + + @Override + public String getDeviceId(String frame) { + return frame.substring(9, 21); + } + + @Override + public String getManufacturerCode(String frame) { + return frame.substring(11, 13); + } + + @Override + public String getMessageType(String frame) { + return frame.substring(21, 23); + } + + @Override + public String getMessageSequence(String frame) { + return frame.substring(23, 25); + } + + @Override + public String getMessageBody(String frame) { + return frame.substring(26, frame.length() - 16); + } + + @Override + public JSONObject parseMessageBody(String messageBody) { + return JSONObject.parseObject(messageBody); + } + + @Override + public String getUptime(String frame) { + return frame.substring(frame.length() - 16, frame.length() - 2); + } + + @Override + public String buildFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append(frame.getMessageBody().toJSONString()); + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } + + @Override + public String buildReplyFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append("00"); // 消息响应类消息 消息体为00 + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/senitnel/controller/SentinelDataController.java b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java new file mode 100644 index 0000000..633c072 --- /dev/null +++ b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java @@ -0,0 +1,120 @@ +package com.casic.senitnel.controller; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.general.ConfigFrame; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import com.casic.senitnel.service.ISentinelFrameService; +import com.casic.util.aep.AepCommandSend; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Base64; +import java.util.Map; + +@Slf4j +@RestController +public class SentinelDataController { + + @Resource + private ISentinelFrameService frameService; + + @Resource + private IBusDeviceService deviceService; + + @RequestMapping("/sentinel/data/recv") + public Object dataRecv(@RequestBody Map map) { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + + JSONObject recvObj = (JSONObject) JSONObject.toJSON(map); + if (recvObj.containsKey("payload")) { + JSONObject payload = recvObj.getJSONObject("payload"); + String value = payload.getString("APPdata"); + + if (value.isEmpty()) { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } else { + byte[] baseBytes = Base64.getDecoder().decode(value); + String frameStr = new String(baseBytes); + + // 根据协议进行解析 + CasicFrame frame = frameService.dataParse(frameStr); + + if (frame != null) { + // 回复响应 + String replyFrameStr = frameService.replyMessage(frame.getDeviceCode(), frame.getSequence()); + + // 从数据库中获取master-api-key 回复响应消息 + BusDevice device = deviceService.getDeviceByCode(frame.getDeviceCode()); + if (device != null && StringUtils.isNotBlank(device.getMasterApiKey())) { + String masterApiKey = device.getMasterApiKey(); + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + + try { + int code = aepCommandSend.handleAndReply(replyFrameStr); + } catch (Exception ex) { + log.error("向设备回复响应异常:{}", ex.getMessage()); + } + } + + // 存库 + frameService.afterAction(frame); + } + + retObj.put("code", 200); + retObj.put("success", true); + } + } else { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } + + return retObj; + } + + @RequestMapping("/sentinel/config/send") + public Object configSend(@RequestBody Map map) throws Exception { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + CasicFrame cmdFrame = new ConfigFrame(); + cmdFrame.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + cmdFrame.setDeviceCode((String) map.get("devCode")); + cmdFrame.setSequence("01"); + cmdFrame.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + JSONObject messageBody = new JSONObject(); + messageBody.put("datas", map.get("cmdList")); + cmdFrame.setMessageBody(messageBody); + + String frameStr = frameService.doBuildCommand(cmdFrame); + + // TODO-LIST + // 这三个参数根据设备编号从数据库中取 + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + String masterApiKey = (String) map.get("masterApiKey"); + + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + int code = aepCommandSend.handleAndReply(frameStr); + + retObj.put("code", 200); + retObj.put("success", true); + retObj.put("AEPRetCode", code); + return retObj; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java new file mode 100644 index 0000000..368af03 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java @@ -0,0 +1,82 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; +import com.casic.dao.model.DataMonitorPipeOther; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class DataFrameNCX extends DataFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + dataItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + DataItemNCX dataItem = new DataItemNCX(); + + dataItem.setLenL(dataObj.getString("LENGL")); + dataItem.setLenR(dataObj.getString("LENGR")); + dataItem.setBat(dataObj.getString("BAT")); + dataItem.setCh4L(dataObj.getString("CH4L")); + dataItem.setCh4R(dataObj.getString("CH4R")); + dataItem.setSlope(dataObj.getString("SLOPING")); + dataItem.setDestroy(dataObj.getString("DESTROY")); + dataItem.setLeak(dataObj.getString("LEAK")); + dataItem.setDiscL(dataObj.getString("DISCL")); + dataItem.setDiscR(dataObj.getString("DISCR")); + dataItem.setVibL(dataObj.getString("VIBL")); + dataItem.setVibR(dataObj.getString("VIBR")); + dataItem.setTime(dataObj.getString("UPTIME")); + + dataItemList.add(dataItem); + } + } + + @Override + public List toDataModelList() { + List dataList = new ArrayList<>(); + for (DataItem dataItem : dataItemList) { + DataMonitorPipeOther data = new DataMonitorPipeOther(); + + data.setDevcode(getDeviceCode()); + data.setLeftLength(((DataItemNCX)dataItem).getLenL()); + data.setRightLength(((DataItemNCX)dataItem).getLenR()); + data.setLeftGas(((DataItemNCX)dataItem).getCh4L()); + data.setRightGas(((DataItemNCX)dataItem).getCh4R()); + data.setVbat(((DataItemNCX)dataItem).getBat()); + data.setPipeInclineAlarm(((DataItemNCX)dataItem).getSlope()); + data.setPipeBreakAlarm(((DataItemNCX)dataItem).getDestroy()); + data.setGasAlarm(((DataItemNCX)dataItem).getLeak()); + data.setLeftOfflineAlarm(((DataItemNCX)dataItem).getDiscL()); + data.setRightOfflineAlarm(((DataItemNCX)dataItem).getDiscR()); + data.setLeftVibrateAlarm(((DataItemNCX)dataItem).getVibL()); + data.setRightVibrateAlarm(((DataItemNCX)dataItem).getVibR()); + data.setUptime(LocalDateTime.parse(((DataItemNCX)dataItem).getTime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 采集时间 + data.setLogtime(LocalDateTime.parse(getUptime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 上报时间 + + dataList.add(data); + } + + return dataList; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java new file mode 100644 index 0000000..372ac73 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java @@ -0,0 +1,31 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.DataItem; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class DataItemNCX extends DataItem { + String lenL; // 左侧指示带长度 + String lenR; // 右侧指示带长度 + String ch4L; // 左侧甲烷浓度值 + String ch4R; // 右侧甲烷浓度值 + String bat; // 电池电压 + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String spare; // 备用 + String time; // 采集时间 + + @Override + public String toString() { + return "气体浓度值:" + "(" + ch4L + "," + ch4R + ")" + "%LEL;" + + "电池电压值:" + bat + "v;" + + "采样时间:" + time; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java new file mode 100644 index 0000000..b3bbcf4 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java @@ -0,0 +1,43 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.EventFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class EventFrameNCX extends EventFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + eventItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + EventItemNCX eventItem = new EventItemNCX(); + + eventItem.setSlope(dataObj.getString("SLOPING")); + eventItem.setDestroy(dataObj.getString("DESTROY")); + eventItem.setLeak(dataObj.getString("LEAK")); + eventItem.setDiscL(dataObj.getString("DISCL")); + eventItem.setDiscR(dataObj.getString("DISCR")); + eventItem.setVibL(dataObj.getString("VIBL")); + eventItem.setVibR(dataObj.getString("VIBR")); + eventItem.setTime(dataObj.getString("UPTIME")); + + eventItemList.add(eventItem); + } + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java new file mode 100644 index 0000000..1a560d0 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java @@ -0,0 +1,49 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.EventItem; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.commons.lang3.StringUtils; + +@EqualsAndHashCode(callSuper = true) +@Data +public class EventItemNCX extends EventItem { + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String time; // 采集时间 + + @Override + public String toString() { + String str = ""; + if (StringUtils.isNotBlank(slope) && slope.equalsIgnoreCase("1")) { + str += "[倾斜报警]"; + } + if (StringUtils.isNotBlank(destroy) && destroy.equalsIgnoreCase("1")) { + str += "[破坏报警]"; + } + if (StringUtils.isNotBlank(leak) && leak.equalsIgnoreCase("1")) { + str += "[甲烷泄漏报警]"; + } + if (StringUtils.isNotBlank(discL) && discL.equalsIgnoreCase("1")) { + str += "[左侧断线报警]"; + } + if (StringUtils.isNotBlank(discR) && discR.equalsIgnoreCase("1")) { + str += "[右侧断线报警]"; + } + if (StringUtils.isNotBlank(vibL) && vibL.equalsIgnoreCase("1")) { + str += "[左侧振动报警]"; + } + if (StringUtils.isNotBlank(vibR) && vibR.equalsIgnoreCase("1")) { + str += "[右侧振动报警]"; + } + str += "采样时间:" + time; + + return str; + + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java new file mode 100644 index 0000000..343c4d6 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java @@ -0,0 +1,37 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class InfoFrameNCX extends CasicFrame { + + String workMode; + String model; + String hwVersion; + String softVersion; + String sensorType; + + @Override + public String toString() { + return "设备编号: " + getDeviceCode() + "; " + + "设备工作模式: " + workMode + " ; " + + "设备型号: " + model + " ; " + + "版本号: " + hwVersion + ", " + softVersion + "; " + + "传感器类型: " + sensorType + " ; " + + "上报时间: " + getUptime(); + } + + @Override + public void parseMessageBody() { + workMode = getMessageBody().getString("WORKMODE"); + model = getMessageBody().getString("MODEL"); + hwVersion = getMessageBody().getString("HWVERSION"); + softVersion = getMessageBody().getString("SOFTVERSION"); + sensorType = getMessageBody().getString("SENSORTYPE"); + } +} diff --git a/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java new file mode 100644 index 0000000..e76fc86 --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java @@ -0,0 +1,14 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; + +public interface ISentinelFrameService { + + CasicFrame dataParse(String frame); + + String replyMessage(String deviceCode, String sequence); + + String doBuildCommand(CasicFrame cmd); + + void afterAction(CasicFrame frame); +} diff --git a/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java new file mode 100644 index 0000000..803ff0e --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java @@ -0,0 +1,109 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; +import com.casic.common.CasicFrameBuildFactory; +import com.casic.common.CasicProtocol; +import com.casic.common.general.DataFrame; +import com.casic.common.general.EventFrame; +import com.casic.common.general.ReplyFrame; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.model.DeviceWellView; +import com.casic.dao.service.IDataSentinelOtherService; +import com.casic.dao.service.IDeviceWellViewService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + + +@Service +@Slf4j +public class SentinelFrameServiceImpl implements ISentinelFrameService { + + @Resource + private CasicProtocol protocol; + + @Resource + IDataSentinelOtherService sentinelDataService; + + @Resource + IDeviceWellViewService deviceService; + + public CasicFrame dataParse(String frame) { + // 1. 判断帧结构 + boolean frameValid = protocol.checkFrame(frame); + if (frameValid) { + // 2. 获取帧结构中的关键字段信息 + String deviceId = protocol.getDeviceId(frame); + String deviceType = protocol.getDeviceType(frame); + String messageType = protocol.getMessageType(frame); + String messageBody = protocol.getMessageBody(frame).toUpperCase(); + String uptime = protocol.getUptime(frame); + String sequence = protocol.getMessageSequence(frame); + + String manufacturerCode = protocol.getManufacturerCode(frame); + CasicFrame sentinelFrame = CasicFrameBuildFactory.buildCasicFrame(messageType, manufacturerCode, deviceType); + + if (sentinelFrame != null) { + sentinelFrame.setDeviceCode(deviceId); + sentinelFrame.setUptime(uptime); + sentinelFrame.setMessageType(messageType); + sentinelFrame.setSequence(sequence); + + // 心跳类的消息不解析MessageBody + if (!sentinelFrame.getMessageType().equals("00")) { + sentinelFrame.setMessageBody(protocol.parseMessageBody(messageBody)); + sentinelFrame.parseMessageBody(); + } + + log.info("收到设备消息:{}", sentinelFrame); + return sentinelFrame; + } + } else { + log.error("消息帧解析异常"); + } + + return null; + } + + @Override + public String replyMessage(String deviceCode, String sequence) { + CasicFrame reply = new ReplyFrame(); + reply.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + reply.setDeviceCode(deviceCode); + reply.setSequence(sequence); + reply.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + return protocol.buildReplyFrameStr(reply); + } + + @Override + public String doBuildCommand(CasicFrame cmd) { + return protocol.buildFrameStr(cmd); + } + + @Override + public void afterAction(CasicFrame frame) { + // 数据消息帧 进行存库操作 + if (frame instanceof DataFrame) { + String devCode = frame.getDeviceCode(); + DeviceWellView devWellView = deviceService.getDeviceWellViewByDevCode(devCode); + String wellCode = ""; + if (devWellView != null) { + wellCode = devWellView.getWellCode(); + } + List dataList = ((DataFrame) frame).toDataModelList(); + if (dataList != null) { + for (Serializable item : dataList) { + DataMonitorPipeOther data = (DataMonitorPipeOther) item; + data.setWellCode(wellCode); + sentinelDataService.save(data); + } + } + } + } +} diff --git a/src/main/java/com/casic/tube/controller/TubeDataController.java b/src/main/java/com/casic/tube/controller/TubeDataController.java index 61486c5..4965449 100644 --- a/src/main/java/com/casic/tube/controller/TubeDataController.java +++ b/src/main/java/com/casic/tube/controller/TubeDataController.java @@ -2,8 +2,8 @@ import com.alibaba.fastjson.JSONObject; import com.casic.common.CasicFrame; -import com.casic.tube.frame.ConfigFrame; -import com.casic.tube.service.ITubeDataService; +import com.casic.common.general.ConfigFrame; +import com.casic.tube.service.ITubeFrameService; import com.casic.util.aep.AepCommandSend; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestBody; @@ -21,7 +21,7 @@ public class TubeDataController { @Resource - private ITubeDataService tubeDataService; + private ITubeFrameService frameService; @RequestMapping("/tube/data/recv") public Object dataRecv(@RequestBody Map map) { @@ -42,10 +42,10 @@ String frameStr = new String(baseBytes); // 根据协议进行解析 - CasicFrame frame = tubeDataService.dataParse(frameStr); + CasicFrame frame = frameService.dataParse(frameStr); // 存库 - tubeDataService.afterAction(frame); + frameService.afterAction(frame); retObj.put("code", 200); retObj.put("success", true); @@ -74,7 +74,7 @@ messageBody.put("datas", map.get("cmdList")); cmdFrame.setMessageBody(messageBody); - String frameStr = tubeDataService.doBuildCommand(cmdFrame); + String frameStr = frameService.doBuildCommand(cmdFrame); // TODO-LIST // 这三个参数根据设备编号从数据库中取 diff --git a/src/main/java/com/casic/tube/frame/ConfigFrame.java b/src/main/java/com/casic/tube/frame/ConfigFrame.java deleted file mode 100644 index 883dad6..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigFrame.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigFrame extends CasicFrame { - - public ConfigFrame() { - setSequence("01"); // 默认序号 - setControl("1"); // 默认为不需要分包 - setMessageType("52"); // 消息大类 52 = SetRequest - } -} diff --git a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java b/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java deleted file mode 100644 index a419145..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigResponseFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "03"; - final String MESSAGE_TYPE_STRING = "SetResponse"; - final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "指令序号" + getSequence() + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/DataFrame.java b/src/main/java/com/casic/tube/frame/DataFrame.java deleted file mode 100644 index 97e07b8..0000000 --- a/src/main/java/com/casic/tube/frame/DataFrame.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import com.casic.dao.model.DataTubeOther; - -import java.util.List; - -public class DataFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "02"; - final String MESSAGE_TYPE_STRING = "Data/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "数据消息/管盯"; - - public List dataItemList; - - public List toDataModelList() { - return null; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append(";"); - builder.append("上报时间:").append(getUptime()).append(";"); - for (DataItem dataItem : dataItemList) { - builder.append("["); - builder.append(dataItem); - builder.append("],"); - } - builder.deleteCharAt(builder.length() - 1); - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/DataItem.java b/src/main/java/com/casic/tube/frame/DataItem.java deleted file mode 100644 index 4e9aceb..0000000 --- a/src/main/java/com/casic/tube/frame/DataItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class DataItem { -} diff --git a/src/main/java/com/casic/tube/frame/EventFrame.java b/src/main/java/com/casic/tube/frame/EventFrame.java deleted file mode 100644 index ea800b4..0000000 --- a/src/main/java/com/casic/tube/frame/EventFrame.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -import java.util.List; - -public class EventFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "01"; - final String MESSAGE_TYPE_STRING = "Event/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "事件消息/管盯"; - - public List eventItemList; - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append("; "); - builder.append("上报时间:").append(getUptime()).append("; "); - for (EventItem eventItem : eventItemList) { - builder.append("["); - builder.append(eventItem); - builder.append("],"); - } - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/EventItem.java b/src/main/java/com/casic/tube/frame/EventItem.java deleted file mode 100644 index a1245bf..0000000 --- a/src/main/java/com/casic/tube/frame/EventItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class EventItem { -} diff --git a/src/main/java/com/casic/tube/frame/HeartFrame.java b/src/main/java/com/casic/tube/frame/HeartFrame.java deleted file mode 100644 index af7e7a6..0000000 --- a/src/main/java/com/casic/tube/frame/HeartFrame.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; - -@Data -public class HeartFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "00"; - final String MESSAGE_TYPE_STRING = "OnlineRequest"; - final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/IMEIFrame.java b/src/main/java/com/casic/tube/frame/IMEIFrame.java deleted file mode 100644 index 9420620..0000000 --- a/src/main/java/com/casic/tube/frame/IMEIFrame.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; - -@Data -public class IMEIFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "05"; - final String MESSAGE_TYPE_STRING = "StartupRequest"; - final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; - - String imei; - String iccid; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "IMEI:" + imei + ";" + - "ICCID:" + iccid + - "}"; - } - - @Override - public void parseMessageBody() { - imei = getMessageBody().getString("IMEI"); - iccid = getMessageBody().getString("ICCID"); - } -} diff --git a/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java b/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java index 50e8a2b..47bf4d6 100644 --- a/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java @@ -3,11 +3,12 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.casic.dao.model.DataTubeOther; -import com.casic.tube.frame.DataFrame; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -19,7 +20,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override @@ -43,8 +45,8 @@ } @Override - public List toDataModelList() { - List dataList = new ArrayList<>(); + public List toDataModelList() { + List dataList = new ArrayList<>(); for (DataItem dataItem : dataItemList) { DataTubeOther data = new DataTubeOther(); diff --git a/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java b/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java index 8d09b10..75e94c7 100644 --- a/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.brs; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java b/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java index 9026b4c..2e5c145 100644 --- a/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java @@ -2,14 +2,11 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.casic.common.CasicFrame; -import com.casic.tube.frame.EventFrame; -import com.casic.tube.frame.EventItem; +import com.casic.common.general.EventFrame; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; -import java.util.List; @Data @Slf4j @@ -17,7 +14,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override diff --git a/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java b/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java index 6c8146c..1792320 100644 --- a/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.brs; -import com.casic.tube.frame.EventItem; +import com.casic.common.general.EventItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java b/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java index e6e541c..b05b358 100644 --- a/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java @@ -3,11 +3,12 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.casic.dao.model.DataTubeOther; -import com.casic.tube.frame.DataFrame; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -19,7 +20,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override @@ -43,8 +45,8 @@ } @Override - public List toDataModelList() { - List dataList = new ArrayList<>(); + public List toDataModelList() { + List dataList = new ArrayList<>(); for (DataItem dataItem : dataItemList) { DataTubeOther data = new DataTubeOther(); diff --git a/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java b/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java index 0aa9bab..e875f2a 100644 --- a/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.mhk; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java b/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java index 9aea120..ec2d005 100644 --- a/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java @@ -2,13 +2,11 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.casic.common.CasicFrame; -import com.casic.tube.frame.EventFrame; +import com.casic.common.general.EventFrame; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; -import java.util.List; @Data @Slf4j @@ -16,7 +14,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java new file mode 100644 index 0000000..95d2bd4 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java @@ -0,0 +1,8 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.DataMonitorPipeOther; + +public interface IDataSentinelOtherService extends IService { + +} diff --git a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java index d6b1200..0290829 100644 --- a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java +++ b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java @@ -1,7 +1,6 @@ package com.casic.dao.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.dao.model.DataTubeOther; import com.casic.dao.model.DeviceWellView; public interface IDeviceWellViewService extends IService { diff --git a/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java new file mode 100644 index 0000000..be34f77 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java @@ -0,0 +1,16 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.BusDeviceMapper; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import org.springframework.stereotype.Service; + +@Service +public class BusDeviceServiceImpl extends ServiceImpl implements IBusDeviceService { + + @Override + public BusDevice getDeviceByCode(String devCode) { + return baseMapper.getOneByDevCode(devCode); + } +} diff --git a/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java new file mode 100644 index 0000000..0db2007 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java @@ -0,0 +1,11 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.DataSentinelOtherMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.service.IDataSentinelOtherService; +import org.springframework.stereotype.Service; + +@Service +public class DataSentinelOtherServiceImpl extends ServiceImpl implements IDataSentinelOtherService { +} diff --git a/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java new file mode 100644 index 0000000..d8c5ef2 --- /dev/null +++ b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java @@ -0,0 +1,111 @@ +package com.casic.protocol; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.CasicProtocol; +import org.springframework.stereotype.Component; + +@Component +public class CasicTubeProtocolImpl implements CasicProtocol { + @Override + public boolean checkFrame(String frame) { + boolean valid = checkFrameHeaderAndTail(frame); + if (valid) { + valid = checkFrameLength(frame); + } + + return valid; + } + + private boolean checkFrameHeaderAndTail(String frame) { + return (frame.substring(0, 2).equalsIgnoreCase("AA")) && + (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); + } + + private boolean checkFrameLength(String frame) { + String lengthStr = frame.substring(4, 7); + int length = Integer.parseInt(lengthStr); + + return frame.length() == length + 9; + } + + @Override + public String getDeviceType(String frame) { + return frame.substring(7, 9); + } + + @Override + public String getDeviceId(String frame) { + return frame.substring(9, 21); + } + + @Override + public String getManufacturerCode(String frame) { + return frame.substring(11, 13); + } + + @Override + public String getMessageType(String frame) { + return frame.substring(21, 23); + } + + @Override + public String getMessageSequence(String frame) { + return frame.substring(23, 25); + } + + @Override + public String getMessageBody(String frame) { + return frame.substring(26, frame.length() - 16); + } + + @Override + public JSONObject parseMessageBody(String messageBody) { + return JSONObject.parseObject(messageBody); + } + + @Override + public String getUptime(String frame) { + return frame.substring(frame.length() - 16, frame.length() - 2); + } + + @Override + public String buildFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append(frame.getMessageBody().toJSONString()); + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } + + @Override + public String buildReplyFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append("00"); // 消息响应类消息 消息体为00 + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/senitnel/controller/SentinelDataController.java b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java new file mode 100644 index 0000000..633c072 --- /dev/null +++ b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java @@ -0,0 +1,120 @@ +package com.casic.senitnel.controller; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.general.ConfigFrame; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import com.casic.senitnel.service.ISentinelFrameService; +import com.casic.util.aep.AepCommandSend; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Base64; +import java.util.Map; + +@Slf4j +@RestController +public class SentinelDataController { + + @Resource + private ISentinelFrameService frameService; + + @Resource + private IBusDeviceService deviceService; + + @RequestMapping("/sentinel/data/recv") + public Object dataRecv(@RequestBody Map map) { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + + JSONObject recvObj = (JSONObject) JSONObject.toJSON(map); + if (recvObj.containsKey("payload")) { + JSONObject payload = recvObj.getJSONObject("payload"); + String value = payload.getString("APPdata"); + + if (value.isEmpty()) { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } else { + byte[] baseBytes = Base64.getDecoder().decode(value); + String frameStr = new String(baseBytes); + + // 根据协议进行解析 + CasicFrame frame = frameService.dataParse(frameStr); + + if (frame != null) { + // 回复响应 + String replyFrameStr = frameService.replyMessage(frame.getDeviceCode(), frame.getSequence()); + + // 从数据库中获取master-api-key 回复响应消息 + BusDevice device = deviceService.getDeviceByCode(frame.getDeviceCode()); + if (device != null && StringUtils.isNotBlank(device.getMasterApiKey())) { + String masterApiKey = device.getMasterApiKey(); + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + + try { + int code = aepCommandSend.handleAndReply(replyFrameStr); + } catch (Exception ex) { + log.error("向设备回复响应异常:{}", ex.getMessage()); + } + } + + // 存库 + frameService.afterAction(frame); + } + + retObj.put("code", 200); + retObj.put("success", true); + } + } else { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } + + return retObj; + } + + @RequestMapping("/sentinel/config/send") + public Object configSend(@RequestBody Map map) throws Exception { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + CasicFrame cmdFrame = new ConfigFrame(); + cmdFrame.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + cmdFrame.setDeviceCode((String) map.get("devCode")); + cmdFrame.setSequence("01"); + cmdFrame.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + JSONObject messageBody = new JSONObject(); + messageBody.put("datas", map.get("cmdList")); + cmdFrame.setMessageBody(messageBody); + + String frameStr = frameService.doBuildCommand(cmdFrame); + + // TODO-LIST + // 这三个参数根据设备编号从数据库中取 + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + String masterApiKey = (String) map.get("masterApiKey"); + + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + int code = aepCommandSend.handleAndReply(frameStr); + + retObj.put("code", 200); + retObj.put("success", true); + retObj.put("AEPRetCode", code); + return retObj; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java new file mode 100644 index 0000000..368af03 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java @@ -0,0 +1,82 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; +import com.casic.dao.model.DataMonitorPipeOther; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class DataFrameNCX extends DataFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + dataItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + DataItemNCX dataItem = new DataItemNCX(); + + dataItem.setLenL(dataObj.getString("LENGL")); + dataItem.setLenR(dataObj.getString("LENGR")); + dataItem.setBat(dataObj.getString("BAT")); + dataItem.setCh4L(dataObj.getString("CH4L")); + dataItem.setCh4R(dataObj.getString("CH4R")); + dataItem.setSlope(dataObj.getString("SLOPING")); + dataItem.setDestroy(dataObj.getString("DESTROY")); + dataItem.setLeak(dataObj.getString("LEAK")); + dataItem.setDiscL(dataObj.getString("DISCL")); + dataItem.setDiscR(dataObj.getString("DISCR")); + dataItem.setVibL(dataObj.getString("VIBL")); + dataItem.setVibR(dataObj.getString("VIBR")); + dataItem.setTime(dataObj.getString("UPTIME")); + + dataItemList.add(dataItem); + } + } + + @Override + public List toDataModelList() { + List dataList = new ArrayList<>(); + for (DataItem dataItem : dataItemList) { + DataMonitorPipeOther data = new DataMonitorPipeOther(); + + data.setDevcode(getDeviceCode()); + data.setLeftLength(((DataItemNCX)dataItem).getLenL()); + data.setRightLength(((DataItemNCX)dataItem).getLenR()); + data.setLeftGas(((DataItemNCX)dataItem).getCh4L()); + data.setRightGas(((DataItemNCX)dataItem).getCh4R()); + data.setVbat(((DataItemNCX)dataItem).getBat()); + data.setPipeInclineAlarm(((DataItemNCX)dataItem).getSlope()); + data.setPipeBreakAlarm(((DataItemNCX)dataItem).getDestroy()); + data.setGasAlarm(((DataItemNCX)dataItem).getLeak()); + data.setLeftOfflineAlarm(((DataItemNCX)dataItem).getDiscL()); + data.setRightOfflineAlarm(((DataItemNCX)dataItem).getDiscR()); + data.setLeftVibrateAlarm(((DataItemNCX)dataItem).getVibL()); + data.setRightVibrateAlarm(((DataItemNCX)dataItem).getVibR()); + data.setUptime(LocalDateTime.parse(((DataItemNCX)dataItem).getTime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 采集时间 + data.setLogtime(LocalDateTime.parse(getUptime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 上报时间 + + dataList.add(data); + } + + return dataList; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java new file mode 100644 index 0000000..372ac73 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java @@ -0,0 +1,31 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.DataItem; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class DataItemNCX extends DataItem { + String lenL; // 左侧指示带长度 + String lenR; // 右侧指示带长度 + String ch4L; // 左侧甲烷浓度值 + String ch4R; // 右侧甲烷浓度值 + String bat; // 电池电压 + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String spare; // 备用 + String time; // 采集时间 + + @Override + public String toString() { + return "气体浓度值:" + "(" + ch4L + "," + ch4R + ")" + "%LEL;" + + "电池电压值:" + bat + "v;" + + "采样时间:" + time; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java new file mode 100644 index 0000000..b3bbcf4 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java @@ -0,0 +1,43 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.EventFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class EventFrameNCX extends EventFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + eventItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + EventItemNCX eventItem = new EventItemNCX(); + + eventItem.setSlope(dataObj.getString("SLOPING")); + eventItem.setDestroy(dataObj.getString("DESTROY")); + eventItem.setLeak(dataObj.getString("LEAK")); + eventItem.setDiscL(dataObj.getString("DISCL")); + eventItem.setDiscR(dataObj.getString("DISCR")); + eventItem.setVibL(dataObj.getString("VIBL")); + eventItem.setVibR(dataObj.getString("VIBR")); + eventItem.setTime(dataObj.getString("UPTIME")); + + eventItemList.add(eventItem); + } + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java new file mode 100644 index 0000000..1a560d0 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java @@ -0,0 +1,49 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.EventItem; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.commons.lang3.StringUtils; + +@EqualsAndHashCode(callSuper = true) +@Data +public class EventItemNCX extends EventItem { + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String time; // 采集时间 + + @Override + public String toString() { + String str = ""; + if (StringUtils.isNotBlank(slope) && slope.equalsIgnoreCase("1")) { + str += "[倾斜报警]"; + } + if (StringUtils.isNotBlank(destroy) && destroy.equalsIgnoreCase("1")) { + str += "[破坏报警]"; + } + if (StringUtils.isNotBlank(leak) && leak.equalsIgnoreCase("1")) { + str += "[甲烷泄漏报警]"; + } + if (StringUtils.isNotBlank(discL) && discL.equalsIgnoreCase("1")) { + str += "[左侧断线报警]"; + } + if (StringUtils.isNotBlank(discR) && discR.equalsIgnoreCase("1")) { + str += "[右侧断线报警]"; + } + if (StringUtils.isNotBlank(vibL) && vibL.equalsIgnoreCase("1")) { + str += "[左侧振动报警]"; + } + if (StringUtils.isNotBlank(vibR) && vibR.equalsIgnoreCase("1")) { + str += "[右侧振动报警]"; + } + str += "采样时间:" + time; + + return str; + + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java new file mode 100644 index 0000000..343c4d6 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java @@ -0,0 +1,37 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class InfoFrameNCX extends CasicFrame { + + String workMode; + String model; + String hwVersion; + String softVersion; + String sensorType; + + @Override + public String toString() { + return "设备编号: " + getDeviceCode() + "; " + + "设备工作模式: " + workMode + " ; " + + "设备型号: " + model + " ; " + + "版本号: " + hwVersion + ", " + softVersion + "; " + + "传感器类型: " + sensorType + " ; " + + "上报时间: " + getUptime(); + } + + @Override + public void parseMessageBody() { + workMode = getMessageBody().getString("WORKMODE"); + model = getMessageBody().getString("MODEL"); + hwVersion = getMessageBody().getString("HWVERSION"); + softVersion = getMessageBody().getString("SOFTVERSION"); + sensorType = getMessageBody().getString("SENSORTYPE"); + } +} diff --git a/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java new file mode 100644 index 0000000..e76fc86 --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java @@ -0,0 +1,14 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; + +public interface ISentinelFrameService { + + CasicFrame dataParse(String frame); + + String replyMessage(String deviceCode, String sequence); + + String doBuildCommand(CasicFrame cmd); + + void afterAction(CasicFrame frame); +} diff --git a/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java new file mode 100644 index 0000000..803ff0e --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java @@ -0,0 +1,109 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; +import com.casic.common.CasicFrameBuildFactory; +import com.casic.common.CasicProtocol; +import com.casic.common.general.DataFrame; +import com.casic.common.general.EventFrame; +import com.casic.common.general.ReplyFrame; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.model.DeviceWellView; +import com.casic.dao.service.IDataSentinelOtherService; +import com.casic.dao.service.IDeviceWellViewService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + + +@Service +@Slf4j +public class SentinelFrameServiceImpl implements ISentinelFrameService { + + @Resource + private CasicProtocol protocol; + + @Resource + IDataSentinelOtherService sentinelDataService; + + @Resource + IDeviceWellViewService deviceService; + + public CasicFrame dataParse(String frame) { + // 1. 判断帧结构 + boolean frameValid = protocol.checkFrame(frame); + if (frameValid) { + // 2. 获取帧结构中的关键字段信息 + String deviceId = protocol.getDeviceId(frame); + String deviceType = protocol.getDeviceType(frame); + String messageType = protocol.getMessageType(frame); + String messageBody = protocol.getMessageBody(frame).toUpperCase(); + String uptime = protocol.getUptime(frame); + String sequence = protocol.getMessageSequence(frame); + + String manufacturerCode = protocol.getManufacturerCode(frame); + CasicFrame sentinelFrame = CasicFrameBuildFactory.buildCasicFrame(messageType, manufacturerCode, deviceType); + + if (sentinelFrame != null) { + sentinelFrame.setDeviceCode(deviceId); + sentinelFrame.setUptime(uptime); + sentinelFrame.setMessageType(messageType); + sentinelFrame.setSequence(sequence); + + // 心跳类的消息不解析MessageBody + if (!sentinelFrame.getMessageType().equals("00")) { + sentinelFrame.setMessageBody(protocol.parseMessageBody(messageBody)); + sentinelFrame.parseMessageBody(); + } + + log.info("收到设备消息:{}", sentinelFrame); + return sentinelFrame; + } + } else { + log.error("消息帧解析异常"); + } + + return null; + } + + @Override + public String replyMessage(String deviceCode, String sequence) { + CasicFrame reply = new ReplyFrame(); + reply.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + reply.setDeviceCode(deviceCode); + reply.setSequence(sequence); + reply.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + return protocol.buildReplyFrameStr(reply); + } + + @Override + public String doBuildCommand(CasicFrame cmd) { + return protocol.buildFrameStr(cmd); + } + + @Override + public void afterAction(CasicFrame frame) { + // 数据消息帧 进行存库操作 + if (frame instanceof DataFrame) { + String devCode = frame.getDeviceCode(); + DeviceWellView devWellView = deviceService.getDeviceWellViewByDevCode(devCode); + String wellCode = ""; + if (devWellView != null) { + wellCode = devWellView.getWellCode(); + } + List dataList = ((DataFrame) frame).toDataModelList(); + if (dataList != null) { + for (Serializable item : dataList) { + DataMonitorPipeOther data = (DataMonitorPipeOther) item; + data.setWellCode(wellCode); + sentinelDataService.save(data); + } + } + } + } +} diff --git a/src/main/java/com/casic/tube/controller/TubeDataController.java b/src/main/java/com/casic/tube/controller/TubeDataController.java index 61486c5..4965449 100644 --- a/src/main/java/com/casic/tube/controller/TubeDataController.java +++ b/src/main/java/com/casic/tube/controller/TubeDataController.java @@ -2,8 +2,8 @@ import com.alibaba.fastjson.JSONObject; import com.casic.common.CasicFrame; -import com.casic.tube.frame.ConfigFrame; -import com.casic.tube.service.ITubeDataService; +import com.casic.common.general.ConfigFrame; +import com.casic.tube.service.ITubeFrameService; import com.casic.util.aep.AepCommandSend; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestBody; @@ -21,7 +21,7 @@ public class TubeDataController { @Resource - private ITubeDataService tubeDataService; + private ITubeFrameService frameService; @RequestMapping("/tube/data/recv") public Object dataRecv(@RequestBody Map map) { @@ -42,10 +42,10 @@ String frameStr = new String(baseBytes); // 根据协议进行解析 - CasicFrame frame = tubeDataService.dataParse(frameStr); + CasicFrame frame = frameService.dataParse(frameStr); // 存库 - tubeDataService.afterAction(frame); + frameService.afterAction(frame); retObj.put("code", 200); retObj.put("success", true); @@ -74,7 +74,7 @@ messageBody.put("datas", map.get("cmdList")); cmdFrame.setMessageBody(messageBody); - String frameStr = tubeDataService.doBuildCommand(cmdFrame); + String frameStr = frameService.doBuildCommand(cmdFrame); // TODO-LIST // 这三个参数根据设备编号从数据库中取 diff --git a/src/main/java/com/casic/tube/frame/ConfigFrame.java b/src/main/java/com/casic/tube/frame/ConfigFrame.java deleted file mode 100644 index 883dad6..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigFrame.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigFrame extends CasicFrame { - - public ConfigFrame() { - setSequence("01"); // 默认序号 - setControl("1"); // 默认为不需要分包 - setMessageType("52"); // 消息大类 52 = SetRequest - } -} diff --git a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java b/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java deleted file mode 100644 index a419145..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigResponseFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "03"; - final String MESSAGE_TYPE_STRING = "SetResponse"; - final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "指令序号" + getSequence() + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/DataFrame.java b/src/main/java/com/casic/tube/frame/DataFrame.java deleted file mode 100644 index 97e07b8..0000000 --- a/src/main/java/com/casic/tube/frame/DataFrame.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import com.casic.dao.model.DataTubeOther; - -import java.util.List; - -public class DataFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "02"; - final String MESSAGE_TYPE_STRING = "Data/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "数据消息/管盯"; - - public List dataItemList; - - public List toDataModelList() { - return null; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append(";"); - builder.append("上报时间:").append(getUptime()).append(";"); - for (DataItem dataItem : dataItemList) { - builder.append("["); - builder.append(dataItem); - builder.append("],"); - } - builder.deleteCharAt(builder.length() - 1); - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/DataItem.java b/src/main/java/com/casic/tube/frame/DataItem.java deleted file mode 100644 index 4e9aceb..0000000 --- a/src/main/java/com/casic/tube/frame/DataItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class DataItem { -} diff --git a/src/main/java/com/casic/tube/frame/EventFrame.java b/src/main/java/com/casic/tube/frame/EventFrame.java deleted file mode 100644 index ea800b4..0000000 --- a/src/main/java/com/casic/tube/frame/EventFrame.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -import java.util.List; - -public class EventFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "01"; - final String MESSAGE_TYPE_STRING = "Event/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "事件消息/管盯"; - - public List eventItemList; - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append("; "); - builder.append("上报时间:").append(getUptime()).append("; "); - for (EventItem eventItem : eventItemList) { - builder.append("["); - builder.append(eventItem); - builder.append("],"); - } - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/EventItem.java b/src/main/java/com/casic/tube/frame/EventItem.java deleted file mode 100644 index a1245bf..0000000 --- a/src/main/java/com/casic/tube/frame/EventItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class EventItem { -} diff --git a/src/main/java/com/casic/tube/frame/HeartFrame.java b/src/main/java/com/casic/tube/frame/HeartFrame.java deleted file mode 100644 index af7e7a6..0000000 --- a/src/main/java/com/casic/tube/frame/HeartFrame.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; - -@Data -public class HeartFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "00"; - final String MESSAGE_TYPE_STRING = "OnlineRequest"; - final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/IMEIFrame.java b/src/main/java/com/casic/tube/frame/IMEIFrame.java deleted file mode 100644 index 9420620..0000000 --- a/src/main/java/com/casic/tube/frame/IMEIFrame.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; - -@Data -public class IMEIFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "05"; - final String MESSAGE_TYPE_STRING = "StartupRequest"; - final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; - - String imei; - String iccid; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "IMEI:" + imei + ";" + - "ICCID:" + iccid + - "}"; - } - - @Override - public void parseMessageBody() { - imei = getMessageBody().getString("IMEI"); - iccid = getMessageBody().getString("ICCID"); - } -} diff --git a/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java b/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java index 50e8a2b..47bf4d6 100644 --- a/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java @@ -3,11 +3,12 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.casic.dao.model.DataTubeOther; -import com.casic.tube.frame.DataFrame; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -19,7 +20,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override @@ -43,8 +45,8 @@ } @Override - public List toDataModelList() { - List dataList = new ArrayList<>(); + public List toDataModelList() { + List dataList = new ArrayList<>(); for (DataItem dataItem : dataItemList) { DataTubeOther data = new DataTubeOther(); diff --git a/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java b/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java index 8d09b10..75e94c7 100644 --- a/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.brs; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java b/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java index 9026b4c..2e5c145 100644 --- a/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java @@ -2,14 +2,11 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.casic.common.CasicFrame; -import com.casic.tube.frame.EventFrame; -import com.casic.tube.frame.EventItem; +import com.casic.common.general.EventFrame; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; -import java.util.List; @Data @Slf4j @@ -17,7 +14,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override diff --git a/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java b/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java index 6c8146c..1792320 100644 --- a/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.brs; -import com.casic.tube.frame.EventItem; +import com.casic.common.general.EventItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java b/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java index e6e541c..b05b358 100644 --- a/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java @@ -3,11 +3,12 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.casic.dao.model.DataTubeOther; -import com.casic.tube.frame.DataFrame; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -19,7 +20,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override @@ -43,8 +45,8 @@ } @Override - public List toDataModelList() { - List dataList = new ArrayList<>(); + public List toDataModelList() { + List dataList = new ArrayList<>(); for (DataItem dataItem : dataItemList) { DataTubeOther data = new DataTubeOther(); diff --git a/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java b/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java index 0aa9bab..e875f2a 100644 --- a/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.mhk; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java b/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java index 9aea120..ec2d005 100644 --- a/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java @@ -2,13 +2,11 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.casic.common.CasicFrame; -import com.casic.tube.frame.EventFrame; +import com.casic.common.general.EventFrame; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; -import java.util.List; @Data @Slf4j @@ -16,7 +14,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override diff --git a/src/main/java/com/casic/tube/frame/mhk/EventItemMHK.java b/src/main/java/com/casic/tube/frame/mhk/EventItemMHK.java index 8f6a536..e5ffed6 100644 --- a/src/main/java/com/casic/tube/frame/mhk/EventItemMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/EventItemMHK.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.mhk; -import com.casic.tube.frame.EventItem; +import com.casic.common.general.EventItem; import lombok.Data; @Data diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java new file mode 100644 index 0000000..95d2bd4 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java @@ -0,0 +1,8 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.DataMonitorPipeOther; + +public interface IDataSentinelOtherService extends IService { + +} diff --git a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java index d6b1200..0290829 100644 --- a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java +++ b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java @@ -1,7 +1,6 @@ package com.casic.dao.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.dao.model.DataTubeOther; import com.casic.dao.model.DeviceWellView; public interface IDeviceWellViewService extends IService { diff --git a/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java new file mode 100644 index 0000000..be34f77 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java @@ -0,0 +1,16 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.BusDeviceMapper; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import org.springframework.stereotype.Service; + +@Service +public class BusDeviceServiceImpl extends ServiceImpl implements IBusDeviceService { + + @Override + public BusDevice getDeviceByCode(String devCode) { + return baseMapper.getOneByDevCode(devCode); + } +} diff --git a/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java new file mode 100644 index 0000000..0db2007 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java @@ -0,0 +1,11 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.DataSentinelOtherMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.service.IDataSentinelOtherService; +import org.springframework.stereotype.Service; + +@Service +public class DataSentinelOtherServiceImpl extends ServiceImpl implements IDataSentinelOtherService { +} diff --git a/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java new file mode 100644 index 0000000..d8c5ef2 --- /dev/null +++ b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java @@ -0,0 +1,111 @@ +package com.casic.protocol; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.CasicProtocol; +import org.springframework.stereotype.Component; + +@Component +public class CasicTubeProtocolImpl implements CasicProtocol { + @Override + public boolean checkFrame(String frame) { + boolean valid = checkFrameHeaderAndTail(frame); + if (valid) { + valid = checkFrameLength(frame); + } + + return valid; + } + + private boolean checkFrameHeaderAndTail(String frame) { + return (frame.substring(0, 2).equalsIgnoreCase("AA")) && + (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); + } + + private boolean checkFrameLength(String frame) { + String lengthStr = frame.substring(4, 7); + int length = Integer.parseInt(lengthStr); + + return frame.length() == length + 9; + } + + @Override + public String getDeviceType(String frame) { + return frame.substring(7, 9); + } + + @Override + public String getDeviceId(String frame) { + return frame.substring(9, 21); + } + + @Override + public String getManufacturerCode(String frame) { + return frame.substring(11, 13); + } + + @Override + public String getMessageType(String frame) { + return frame.substring(21, 23); + } + + @Override + public String getMessageSequence(String frame) { + return frame.substring(23, 25); + } + + @Override + public String getMessageBody(String frame) { + return frame.substring(26, frame.length() - 16); + } + + @Override + public JSONObject parseMessageBody(String messageBody) { + return JSONObject.parseObject(messageBody); + } + + @Override + public String getUptime(String frame) { + return frame.substring(frame.length() - 16, frame.length() - 2); + } + + @Override + public String buildFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append(frame.getMessageBody().toJSONString()); + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } + + @Override + public String buildReplyFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append("00"); // 消息响应类消息 消息体为00 + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/senitnel/controller/SentinelDataController.java b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java new file mode 100644 index 0000000..633c072 --- /dev/null +++ b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java @@ -0,0 +1,120 @@ +package com.casic.senitnel.controller; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.general.ConfigFrame; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import com.casic.senitnel.service.ISentinelFrameService; +import com.casic.util.aep.AepCommandSend; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Base64; +import java.util.Map; + +@Slf4j +@RestController +public class SentinelDataController { + + @Resource + private ISentinelFrameService frameService; + + @Resource + private IBusDeviceService deviceService; + + @RequestMapping("/sentinel/data/recv") + public Object dataRecv(@RequestBody Map map) { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + + JSONObject recvObj = (JSONObject) JSONObject.toJSON(map); + if (recvObj.containsKey("payload")) { + JSONObject payload = recvObj.getJSONObject("payload"); + String value = payload.getString("APPdata"); + + if (value.isEmpty()) { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } else { + byte[] baseBytes = Base64.getDecoder().decode(value); + String frameStr = new String(baseBytes); + + // 根据协议进行解析 + CasicFrame frame = frameService.dataParse(frameStr); + + if (frame != null) { + // 回复响应 + String replyFrameStr = frameService.replyMessage(frame.getDeviceCode(), frame.getSequence()); + + // 从数据库中获取master-api-key 回复响应消息 + BusDevice device = deviceService.getDeviceByCode(frame.getDeviceCode()); + if (device != null && StringUtils.isNotBlank(device.getMasterApiKey())) { + String masterApiKey = device.getMasterApiKey(); + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + + try { + int code = aepCommandSend.handleAndReply(replyFrameStr); + } catch (Exception ex) { + log.error("向设备回复响应异常:{}", ex.getMessage()); + } + } + + // 存库 + frameService.afterAction(frame); + } + + retObj.put("code", 200); + retObj.put("success", true); + } + } else { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } + + return retObj; + } + + @RequestMapping("/sentinel/config/send") + public Object configSend(@RequestBody Map map) throws Exception { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + CasicFrame cmdFrame = new ConfigFrame(); + cmdFrame.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + cmdFrame.setDeviceCode((String) map.get("devCode")); + cmdFrame.setSequence("01"); + cmdFrame.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + JSONObject messageBody = new JSONObject(); + messageBody.put("datas", map.get("cmdList")); + cmdFrame.setMessageBody(messageBody); + + String frameStr = frameService.doBuildCommand(cmdFrame); + + // TODO-LIST + // 这三个参数根据设备编号从数据库中取 + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + String masterApiKey = (String) map.get("masterApiKey"); + + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + int code = aepCommandSend.handleAndReply(frameStr); + + retObj.put("code", 200); + retObj.put("success", true); + retObj.put("AEPRetCode", code); + return retObj; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java new file mode 100644 index 0000000..368af03 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java @@ -0,0 +1,82 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; +import com.casic.dao.model.DataMonitorPipeOther; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class DataFrameNCX extends DataFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + dataItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + DataItemNCX dataItem = new DataItemNCX(); + + dataItem.setLenL(dataObj.getString("LENGL")); + dataItem.setLenR(dataObj.getString("LENGR")); + dataItem.setBat(dataObj.getString("BAT")); + dataItem.setCh4L(dataObj.getString("CH4L")); + dataItem.setCh4R(dataObj.getString("CH4R")); + dataItem.setSlope(dataObj.getString("SLOPING")); + dataItem.setDestroy(dataObj.getString("DESTROY")); + dataItem.setLeak(dataObj.getString("LEAK")); + dataItem.setDiscL(dataObj.getString("DISCL")); + dataItem.setDiscR(dataObj.getString("DISCR")); + dataItem.setVibL(dataObj.getString("VIBL")); + dataItem.setVibR(dataObj.getString("VIBR")); + dataItem.setTime(dataObj.getString("UPTIME")); + + dataItemList.add(dataItem); + } + } + + @Override + public List toDataModelList() { + List dataList = new ArrayList<>(); + for (DataItem dataItem : dataItemList) { + DataMonitorPipeOther data = new DataMonitorPipeOther(); + + data.setDevcode(getDeviceCode()); + data.setLeftLength(((DataItemNCX)dataItem).getLenL()); + data.setRightLength(((DataItemNCX)dataItem).getLenR()); + data.setLeftGas(((DataItemNCX)dataItem).getCh4L()); + data.setRightGas(((DataItemNCX)dataItem).getCh4R()); + data.setVbat(((DataItemNCX)dataItem).getBat()); + data.setPipeInclineAlarm(((DataItemNCX)dataItem).getSlope()); + data.setPipeBreakAlarm(((DataItemNCX)dataItem).getDestroy()); + data.setGasAlarm(((DataItemNCX)dataItem).getLeak()); + data.setLeftOfflineAlarm(((DataItemNCX)dataItem).getDiscL()); + data.setRightOfflineAlarm(((DataItemNCX)dataItem).getDiscR()); + data.setLeftVibrateAlarm(((DataItemNCX)dataItem).getVibL()); + data.setRightVibrateAlarm(((DataItemNCX)dataItem).getVibR()); + data.setUptime(LocalDateTime.parse(((DataItemNCX)dataItem).getTime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 采集时间 + data.setLogtime(LocalDateTime.parse(getUptime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 上报时间 + + dataList.add(data); + } + + return dataList; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java new file mode 100644 index 0000000..372ac73 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java @@ -0,0 +1,31 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.DataItem; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class DataItemNCX extends DataItem { + String lenL; // 左侧指示带长度 + String lenR; // 右侧指示带长度 + String ch4L; // 左侧甲烷浓度值 + String ch4R; // 右侧甲烷浓度值 + String bat; // 电池电压 + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String spare; // 备用 + String time; // 采集时间 + + @Override + public String toString() { + return "气体浓度值:" + "(" + ch4L + "," + ch4R + ")" + "%LEL;" + + "电池电压值:" + bat + "v;" + + "采样时间:" + time; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java new file mode 100644 index 0000000..b3bbcf4 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java @@ -0,0 +1,43 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.EventFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class EventFrameNCX extends EventFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + eventItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + EventItemNCX eventItem = new EventItemNCX(); + + eventItem.setSlope(dataObj.getString("SLOPING")); + eventItem.setDestroy(dataObj.getString("DESTROY")); + eventItem.setLeak(dataObj.getString("LEAK")); + eventItem.setDiscL(dataObj.getString("DISCL")); + eventItem.setDiscR(dataObj.getString("DISCR")); + eventItem.setVibL(dataObj.getString("VIBL")); + eventItem.setVibR(dataObj.getString("VIBR")); + eventItem.setTime(dataObj.getString("UPTIME")); + + eventItemList.add(eventItem); + } + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java new file mode 100644 index 0000000..1a560d0 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java @@ -0,0 +1,49 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.EventItem; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.commons.lang3.StringUtils; + +@EqualsAndHashCode(callSuper = true) +@Data +public class EventItemNCX extends EventItem { + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String time; // 采集时间 + + @Override + public String toString() { + String str = ""; + if (StringUtils.isNotBlank(slope) && slope.equalsIgnoreCase("1")) { + str += "[倾斜报警]"; + } + if (StringUtils.isNotBlank(destroy) && destroy.equalsIgnoreCase("1")) { + str += "[破坏报警]"; + } + if (StringUtils.isNotBlank(leak) && leak.equalsIgnoreCase("1")) { + str += "[甲烷泄漏报警]"; + } + if (StringUtils.isNotBlank(discL) && discL.equalsIgnoreCase("1")) { + str += "[左侧断线报警]"; + } + if (StringUtils.isNotBlank(discR) && discR.equalsIgnoreCase("1")) { + str += "[右侧断线报警]"; + } + if (StringUtils.isNotBlank(vibL) && vibL.equalsIgnoreCase("1")) { + str += "[左侧振动报警]"; + } + if (StringUtils.isNotBlank(vibR) && vibR.equalsIgnoreCase("1")) { + str += "[右侧振动报警]"; + } + str += "采样时间:" + time; + + return str; + + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java new file mode 100644 index 0000000..343c4d6 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java @@ -0,0 +1,37 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class InfoFrameNCX extends CasicFrame { + + String workMode; + String model; + String hwVersion; + String softVersion; + String sensorType; + + @Override + public String toString() { + return "设备编号: " + getDeviceCode() + "; " + + "设备工作模式: " + workMode + " ; " + + "设备型号: " + model + " ; " + + "版本号: " + hwVersion + ", " + softVersion + "; " + + "传感器类型: " + sensorType + " ; " + + "上报时间: " + getUptime(); + } + + @Override + public void parseMessageBody() { + workMode = getMessageBody().getString("WORKMODE"); + model = getMessageBody().getString("MODEL"); + hwVersion = getMessageBody().getString("HWVERSION"); + softVersion = getMessageBody().getString("SOFTVERSION"); + sensorType = getMessageBody().getString("SENSORTYPE"); + } +} diff --git a/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java new file mode 100644 index 0000000..e76fc86 --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java @@ -0,0 +1,14 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; + +public interface ISentinelFrameService { + + CasicFrame dataParse(String frame); + + String replyMessage(String deviceCode, String sequence); + + String doBuildCommand(CasicFrame cmd); + + void afterAction(CasicFrame frame); +} diff --git a/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java new file mode 100644 index 0000000..803ff0e --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java @@ -0,0 +1,109 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; +import com.casic.common.CasicFrameBuildFactory; +import com.casic.common.CasicProtocol; +import com.casic.common.general.DataFrame; +import com.casic.common.general.EventFrame; +import com.casic.common.general.ReplyFrame; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.model.DeviceWellView; +import com.casic.dao.service.IDataSentinelOtherService; +import com.casic.dao.service.IDeviceWellViewService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + + +@Service +@Slf4j +public class SentinelFrameServiceImpl implements ISentinelFrameService { + + @Resource + private CasicProtocol protocol; + + @Resource + IDataSentinelOtherService sentinelDataService; + + @Resource + IDeviceWellViewService deviceService; + + public CasicFrame dataParse(String frame) { + // 1. 判断帧结构 + boolean frameValid = protocol.checkFrame(frame); + if (frameValid) { + // 2. 获取帧结构中的关键字段信息 + String deviceId = protocol.getDeviceId(frame); + String deviceType = protocol.getDeviceType(frame); + String messageType = protocol.getMessageType(frame); + String messageBody = protocol.getMessageBody(frame).toUpperCase(); + String uptime = protocol.getUptime(frame); + String sequence = protocol.getMessageSequence(frame); + + String manufacturerCode = protocol.getManufacturerCode(frame); + CasicFrame sentinelFrame = CasicFrameBuildFactory.buildCasicFrame(messageType, manufacturerCode, deviceType); + + if (sentinelFrame != null) { + sentinelFrame.setDeviceCode(deviceId); + sentinelFrame.setUptime(uptime); + sentinelFrame.setMessageType(messageType); + sentinelFrame.setSequence(sequence); + + // 心跳类的消息不解析MessageBody + if (!sentinelFrame.getMessageType().equals("00")) { + sentinelFrame.setMessageBody(protocol.parseMessageBody(messageBody)); + sentinelFrame.parseMessageBody(); + } + + log.info("收到设备消息:{}", sentinelFrame); + return sentinelFrame; + } + } else { + log.error("消息帧解析异常"); + } + + return null; + } + + @Override + public String replyMessage(String deviceCode, String sequence) { + CasicFrame reply = new ReplyFrame(); + reply.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + reply.setDeviceCode(deviceCode); + reply.setSequence(sequence); + reply.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + return protocol.buildReplyFrameStr(reply); + } + + @Override + public String doBuildCommand(CasicFrame cmd) { + return protocol.buildFrameStr(cmd); + } + + @Override + public void afterAction(CasicFrame frame) { + // 数据消息帧 进行存库操作 + if (frame instanceof DataFrame) { + String devCode = frame.getDeviceCode(); + DeviceWellView devWellView = deviceService.getDeviceWellViewByDevCode(devCode); + String wellCode = ""; + if (devWellView != null) { + wellCode = devWellView.getWellCode(); + } + List dataList = ((DataFrame) frame).toDataModelList(); + if (dataList != null) { + for (Serializable item : dataList) { + DataMonitorPipeOther data = (DataMonitorPipeOther) item; + data.setWellCode(wellCode); + sentinelDataService.save(data); + } + } + } + } +} diff --git a/src/main/java/com/casic/tube/controller/TubeDataController.java b/src/main/java/com/casic/tube/controller/TubeDataController.java index 61486c5..4965449 100644 --- a/src/main/java/com/casic/tube/controller/TubeDataController.java +++ b/src/main/java/com/casic/tube/controller/TubeDataController.java @@ -2,8 +2,8 @@ import com.alibaba.fastjson.JSONObject; import com.casic.common.CasicFrame; -import com.casic.tube.frame.ConfigFrame; -import com.casic.tube.service.ITubeDataService; +import com.casic.common.general.ConfigFrame; +import com.casic.tube.service.ITubeFrameService; import com.casic.util.aep.AepCommandSend; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestBody; @@ -21,7 +21,7 @@ public class TubeDataController { @Resource - private ITubeDataService tubeDataService; + private ITubeFrameService frameService; @RequestMapping("/tube/data/recv") public Object dataRecv(@RequestBody Map map) { @@ -42,10 +42,10 @@ String frameStr = new String(baseBytes); // 根据协议进行解析 - CasicFrame frame = tubeDataService.dataParse(frameStr); + CasicFrame frame = frameService.dataParse(frameStr); // 存库 - tubeDataService.afterAction(frame); + frameService.afterAction(frame); retObj.put("code", 200); retObj.put("success", true); @@ -74,7 +74,7 @@ messageBody.put("datas", map.get("cmdList")); cmdFrame.setMessageBody(messageBody); - String frameStr = tubeDataService.doBuildCommand(cmdFrame); + String frameStr = frameService.doBuildCommand(cmdFrame); // TODO-LIST // 这三个参数根据设备编号从数据库中取 diff --git a/src/main/java/com/casic/tube/frame/ConfigFrame.java b/src/main/java/com/casic/tube/frame/ConfigFrame.java deleted file mode 100644 index 883dad6..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigFrame.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigFrame extends CasicFrame { - - public ConfigFrame() { - setSequence("01"); // 默认序号 - setControl("1"); // 默认为不需要分包 - setMessageType("52"); // 消息大类 52 = SetRequest - } -} diff --git a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java b/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java deleted file mode 100644 index a419145..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigResponseFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "03"; - final String MESSAGE_TYPE_STRING = "SetResponse"; - final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "指令序号" + getSequence() + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/DataFrame.java b/src/main/java/com/casic/tube/frame/DataFrame.java deleted file mode 100644 index 97e07b8..0000000 --- a/src/main/java/com/casic/tube/frame/DataFrame.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import com.casic.dao.model.DataTubeOther; - -import java.util.List; - -public class DataFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "02"; - final String MESSAGE_TYPE_STRING = "Data/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "数据消息/管盯"; - - public List dataItemList; - - public List toDataModelList() { - return null; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append(";"); - builder.append("上报时间:").append(getUptime()).append(";"); - for (DataItem dataItem : dataItemList) { - builder.append("["); - builder.append(dataItem); - builder.append("],"); - } - builder.deleteCharAt(builder.length() - 1); - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/DataItem.java b/src/main/java/com/casic/tube/frame/DataItem.java deleted file mode 100644 index 4e9aceb..0000000 --- a/src/main/java/com/casic/tube/frame/DataItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class DataItem { -} diff --git a/src/main/java/com/casic/tube/frame/EventFrame.java b/src/main/java/com/casic/tube/frame/EventFrame.java deleted file mode 100644 index ea800b4..0000000 --- a/src/main/java/com/casic/tube/frame/EventFrame.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -import java.util.List; - -public class EventFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "01"; - final String MESSAGE_TYPE_STRING = "Event/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "事件消息/管盯"; - - public List eventItemList; - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append("; "); - builder.append("上报时间:").append(getUptime()).append("; "); - for (EventItem eventItem : eventItemList) { - builder.append("["); - builder.append(eventItem); - builder.append("],"); - } - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/EventItem.java b/src/main/java/com/casic/tube/frame/EventItem.java deleted file mode 100644 index a1245bf..0000000 --- a/src/main/java/com/casic/tube/frame/EventItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class EventItem { -} diff --git a/src/main/java/com/casic/tube/frame/HeartFrame.java b/src/main/java/com/casic/tube/frame/HeartFrame.java deleted file mode 100644 index af7e7a6..0000000 --- a/src/main/java/com/casic/tube/frame/HeartFrame.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; - -@Data -public class HeartFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "00"; - final String MESSAGE_TYPE_STRING = "OnlineRequest"; - final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/IMEIFrame.java b/src/main/java/com/casic/tube/frame/IMEIFrame.java deleted file mode 100644 index 9420620..0000000 --- a/src/main/java/com/casic/tube/frame/IMEIFrame.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; - -@Data -public class IMEIFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "05"; - final String MESSAGE_TYPE_STRING = "StartupRequest"; - final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; - - String imei; - String iccid; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "IMEI:" + imei + ";" + - "ICCID:" + iccid + - "}"; - } - - @Override - public void parseMessageBody() { - imei = getMessageBody().getString("IMEI"); - iccid = getMessageBody().getString("ICCID"); - } -} diff --git a/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java b/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java index 50e8a2b..47bf4d6 100644 --- a/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java @@ -3,11 +3,12 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.casic.dao.model.DataTubeOther; -import com.casic.tube.frame.DataFrame; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -19,7 +20,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override @@ -43,8 +45,8 @@ } @Override - public List toDataModelList() { - List dataList = new ArrayList<>(); + public List toDataModelList() { + List dataList = new ArrayList<>(); for (DataItem dataItem : dataItemList) { DataTubeOther data = new DataTubeOther(); diff --git a/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java b/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java index 8d09b10..75e94c7 100644 --- a/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.brs; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java b/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java index 9026b4c..2e5c145 100644 --- a/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java @@ -2,14 +2,11 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.casic.common.CasicFrame; -import com.casic.tube.frame.EventFrame; -import com.casic.tube.frame.EventItem; +import com.casic.common.general.EventFrame; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; -import java.util.List; @Data @Slf4j @@ -17,7 +14,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override diff --git a/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java b/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java index 6c8146c..1792320 100644 --- a/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.brs; -import com.casic.tube.frame.EventItem; +import com.casic.common.general.EventItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java b/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java index e6e541c..b05b358 100644 --- a/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java @@ -3,11 +3,12 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.casic.dao.model.DataTubeOther; -import com.casic.tube.frame.DataFrame; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -19,7 +20,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override @@ -43,8 +45,8 @@ } @Override - public List toDataModelList() { - List dataList = new ArrayList<>(); + public List toDataModelList() { + List dataList = new ArrayList<>(); for (DataItem dataItem : dataItemList) { DataTubeOther data = new DataTubeOther(); diff --git a/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java b/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java index 0aa9bab..e875f2a 100644 --- a/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.mhk; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java b/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java index 9aea120..ec2d005 100644 --- a/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java @@ -2,13 +2,11 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.casic.common.CasicFrame; -import com.casic.tube.frame.EventFrame; +import com.casic.common.general.EventFrame; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; -import java.util.List; @Data @Slf4j @@ -16,7 +14,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override diff --git a/src/main/java/com/casic/tube/frame/mhk/EventItemMHK.java b/src/main/java/com/casic/tube/frame/mhk/EventItemMHK.java index 8f6a536..e5ffed6 100644 --- a/src/main/java/com/casic/tube/frame/mhk/EventItemMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/EventItemMHK.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.mhk; -import com.casic.tube.frame.EventItem; +import com.casic.common.general.EventItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/tp/DataFrameHTTP.java b/src/main/java/com/casic/tube/frame/tp/DataFrameHTTP.java index 23df423..69b7c1f 100644 --- a/src/main/java/com/casic/tube/frame/tp/DataFrameHTTP.java +++ b/src/main/java/com/casic/tube/frame/tp/DataFrameHTTP.java @@ -3,11 +3,12 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.casic.dao.model.DataTubeOther; -import com.casic.tube.frame.DataFrame; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -18,6 +19,12 @@ public class DataFrameHTTP extends DataFrame { @Override + public String toString(){ + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); + } + + @Override public void parseMessageBody() { JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); dataItemList = new ArrayList<>(); @@ -40,8 +47,8 @@ } @Override - public List toDataModelList() { - List dataList = new ArrayList<>(); + public List toDataModelList() { + List dataList = new ArrayList<>(); for (DataItem dataItem : dataItemList) { DataTubeOther data = new DataTubeOther(); diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java new file mode 100644 index 0000000..95d2bd4 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java @@ -0,0 +1,8 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.DataMonitorPipeOther; + +public interface IDataSentinelOtherService extends IService { + +} diff --git a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java index d6b1200..0290829 100644 --- a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java +++ b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java @@ -1,7 +1,6 @@ package com.casic.dao.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.dao.model.DataTubeOther; import com.casic.dao.model.DeviceWellView; public interface IDeviceWellViewService extends IService { diff --git a/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java new file mode 100644 index 0000000..be34f77 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java @@ -0,0 +1,16 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.BusDeviceMapper; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import org.springframework.stereotype.Service; + +@Service +public class BusDeviceServiceImpl extends ServiceImpl implements IBusDeviceService { + + @Override + public BusDevice getDeviceByCode(String devCode) { + return baseMapper.getOneByDevCode(devCode); + } +} diff --git a/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java new file mode 100644 index 0000000..0db2007 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java @@ -0,0 +1,11 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.DataSentinelOtherMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.service.IDataSentinelOtherService; +import org.springframework.stereotype.Service; + +@Service +public class DataSentinelOtherServiceImpl extends ServiceImpl implements IDataSentinelOtherService { +} diff --git a/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java new file mode 100644 index 0000000..d8c5ef2 --- /dev/null +++ b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java @@ -0,0 +1,111 @@ +package com.casic.protocol; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.CasicProtocol; +import org.springframework.stereotype.Component; + +@Component +public class CasicTubeProtocolImpl implements CasicProtocol { + @Override + public boolean checkFrame(String frame) { + boolean valid = checkFrameHeaderAndTail(frame); + if (valid) { + valid = checkFrameLength(frame); + } + + return valid; + } + + private boolean checkFrameHeaderAndTail(String frame) { + return (frame.substring(0, 2).equalsIgnoreCase("AA")) && + (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); + } + + private boolean checkFrameLength(String frame) { + String lengthStr = frame.substring(4, 7); + int length = Integer.parseInt(lengthStr); + + return frame.length() == length + 9; + } + + @Override + public String getDeviceType(String frame) { + return frame.substring(7, 9); + } + + @Override + public String getDeviceId(String frame) { + return frame.substring(9, 21); + } + + @Override + public String getManufacturerCode(String frame) { + return frame.substring(11, 13); + } + + @Override + public String getMessageType(String frame) { + return frame.substring(21, 23); + } + + @Override + public String getMessageSequence(String frame) { + return frame.substring(23, 25); + } + + @Override + public String getMessageBody(String frame) { + return frame.substring(26, frame.length() - 16); + } + + @Override + public JSONObject parseMessageBody(String messageBody) { + return JSONObject.parseObject(messageBody); + } + + @Override + public String getUptime(String frame) { + return frame.substring(frame.length() - 16, frame.length() - 2); + } + + @Override + public String buildFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append(frame.getMessageBody().toJSONString()); + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } + + @Override + public String buildReplyFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append("00"); // 消息响应类消息 消息体为00 + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/senitnel/controller/SentinelDataController.java b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java new file mode 100644 index 0000000..633c072 --- /dev/null +++ b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java @@ -0,0 +1,120 @@ +package com.casic.senitnel.controller; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.general.ConfigFrame; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import com.casic.senitnel.service.ISentinelFrameService; +import com.casic.util.aep.AepCommandSend; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Base64; +import java.util.Map; + +@Slf4j +@RestController +public class SentinelDataController { + + @Resource + private ISentinelFrameService frameService; + + @Resource + private IBusDeviceService deviceService; + + @RequestMapping("/sentinel/data/recv") + public Object dataRecv(@RequestBody Map map) { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + + JSONObject recvObj = (JSONObject) JSONObject.toJSON(map); + if (recvObj.containsKey("payload")) { + JSONObject payload = recvObj.getJSONObject("payload"); + String value = payload.getString("APPdata"); + + if (value.isEmpty()) { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } else { + byte[] baseBytes = Base64.getDecoder().decode(value); + String frameStr = new String(baseBytes); + + // 根据协议进行解析 + CasicFrame frame = frameService.dataParse(frameStr); + + if (frame != null) { + // 回复响应 + String replyFrameStr = frameService.replyMessage(frame.getDeviceCode(), frame.getSequence()); + + // 从数据库中获取master-api-key 回复响应消息 + BusDevice device = deviceService.getDeviceByCode(frame.getDeviceCode()); + if (device != null && StringUtils.isNotBlank(device.getMasterApiKey())) { + String masterApiKey = device.getMasterApiKey(); + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + + try { + int code = aepCommandSend.handleAndReply(replyFrameStr); + } catch (Exception ex) { + log.error("向设备回复响应异常:{}", ex.getMessage()); + } + } + + // 存库 + frameService.afterAction(frame); + } + + retObj.put("code", 200); + retObj.put("success", true); + } + } else { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } + + return retObj; + } + + @RequestMapping("/sentinel/config/send") + public Object configSend(@RequestBody Map map) throws Exception { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + CasicFrame cmdFrame = new ConfigFrame(); + cmdFrame.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + cmdFrame.setDeviceCode((String) map.get("devCode")); + cmdFrame.setSequence("01"); + cmdFrame.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + JSONObject messageBody = new JSONObject(); + messageBody.put("datas", map.get("cmdList")); + cmdFrame.setMessageBody(messageBody); + + String frameStr = frameService.doBuildCommand(cmdFrame); + + // TODO-LIST + // 这三个参数根据设备编号从数据库中取 + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + String masterApiKey = (String) map.get("masterApiKey"); + + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + int code = aepCommandSend.handleAndReply(frameStr); + + retObj.put("code", 200); + retObj.put("success", true); + retObj.put("AEPRetCode", code); + return retObj; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java new file mode 100644 index 0000000..368af03 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java @@ -0,0 +1,82 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; +import com.casic.dao.model.DataMonitorPipeOther; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class DataFrameNCX extends DataFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + dataItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + DataItemNCX dataItem = new DataItemNCX(); + + dataItem.setLenL(dataObj.getString("LENGL")); + dataItem.setLenR(dataObj.getString("LENGR")); + dataItem.setBat(dataObj.getString("BAT")); + dataItem.setCh4L(dataObj.getString("CH4L")); + dataItem.setCh4R(dataObj.getString("CH4R")); + dataItem.setSlope(dataObj.getString("SLOPING")); + dataItem.setDestroy(dataObj.getString("DESTROY")); + dataItem.setLeak(dataObj.getString("LEAK")); + dataItem.setDiscL(dataObj.getString("DISCL")); + dataItem.setDiscR(dataObj.getString("DISCR")); + dataItem.setVibL(dataObj.getString("VIBL")); + dataItem.setVibR(dataObj.getString("VIBR")); + dataItem.setTime(dataObj.getString("UPTIME")); + + dataItemList.add(dataItem); + } + } + + @Override + public List toDataModelList() { + List dataList = new ArrayList<>(); + for (DataItem dataItem : dataItemList) { + DataMonitorPipeOther data = new DataMonitorPipeOther(); + + data.setDevcode(getDeviceCode()); + data.setLeftLength(((DataItemNCX)dataItem).getLenL()); + data.setRightLength(((DataItemNCX)dataItem).getLenR()); + data.setLeftGas(((DataItemNCX)dataItem).getCh4L()); + data.setRightGas(((DataItemNCX)dataItem).getCh4R()); + data.setVbat(((DataItemNCX)dataItem).getBat()); + data.setPipeInclineAlarm(((DataItemNCX)dataItem).getSlope()); + data.setPipeBreakAlarm(((DataItemNCX)dataItem).getDestroy()); + data.setGasAlarm(((DataItemNCX)dataItem).getLeak()); + data.setLeftOfflineAlarm(((DataItemNCX)dataItem).getDiscL()); + data.setRightOfflineAlarm(((DataItemNCX)dataItem).getDiscR()); + data.setLeftVibrateAlarm(((DataItemNCX)dataItem).getVibL()); + data.setRightVibrateAlarm(((DataItemNCX)dataItem).getVibR()); + data.setUptime(LocalDateTime.parse(((DataItemNCX)dataItem).getTime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 采集时间 + data.setLogtime(LocalDateTime.parse(getUptime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 上报时间 + + dataList.add(data); + } + + return dataList; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java new file mode 100644 index 0000000..372ac73 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java @@ -0,0 +1,31 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.DataItem; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class DataItemNCX extends DataItem { + String lenL; // 左侧指示带长度 + String lenR; // 右侧指示带长度 + String ch4L; // 左侧甲烷浓度值 + String ch4R; // 右侧甲烷浓度值 + String bat; // 电池电压 + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String spare; // 备用 + String time; // 采集时间 + + @Override + public String toString() { + return "气体浓度值:" + "(" + ch4L + "," + ch4R + ")" + "%LEL;" + + "电池电压值:" + bat + "v;" + + "采样时间:" + time; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java new file mode 100644 index 0000000..b3bbcf4 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java @@ -0,0 +1,43 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.EventFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class EventFrameNCX extends EventFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + eventItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + EventItemNCX eventItem = new EventItemNCX(); + + eventItem.setSlope(dataObj.getString("SLOPING")); + eventItem.setDestroy(dataObj.getString("DESTROY")); + eventItem.setLeak(dataObj.getString("LEAK")); + eventItem.setDiscL(dataObj.getString("DISCL")); + eventItem.setDiscR(dataObj.getString("DISCR")); + eventItem.setVibL(dataObj.getString("VIBL")); + eventItem.setVibR(dataObj.getString("VIBR")); + eventItem.setTime(dataObj.getString("UPTIME")); + + eventItemList.add(eventItem); + } + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java new file mode 100644 index 0000000..1a560d0 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java @@ -0,0 +1,49 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.EventItem; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.commons.lang3.StringUtils; + +@EqualsAndHashCode(callSuper = true) +@Data +public class EventItemNCX extends EventItem { + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String time; // 采集时间 + + @Override + public String toString() { + String str = ""; + if (StringUtils.isNotBlank(slope) && slope.equalsIgnoreCase("1")) { + str += "[倾斜报警]"; + } + if (StringUtils.isNotBlank(destroy) && destroy.equalsIgnoreCase("1")) { + str += "[破坏报警]"; + } + if (StringUtils.isNotBlank(leak) && leak.equalsIgnoreCase("1")) { + str += "[甲烷泄漏报警]"; + } + if (StringUtils.isNotBlank(discL) && discL.equalsIgnoreCase("1")) { + str += "[左侧断线报警]"; + } + if (StringUtils.isNotBlank(discR) && discR.equalsIgnoreCase("1")) { + str += "[右侧断线报警]"; + } + if (StringUtils.isNotBlank(vibL) && vibL.equalsIgnoreCase("1")) { + str += "[左侧振动报警]"; + } + if (StringUtils.isNotBlank(vibR) && vibR.equalsIgnoreCase("1")) { + str += "[右侧振动报警]"; + } + str += "采样时间:" + time; + + return str; + + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java new file mode 100644 index 0000000..343c4d6 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java @@ -0,0 +1,37 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class InfoFrameNCX extends CasicFrame { + + String workMode; + String model; + String hwVersion; + String softVersion; + String sensorType; + + @Override + public String toString() { + return "设备编号: " + getDeviceCode() + "; " + + "设备工作模式: " + workMode + " ; " + + "设备型号: " + model + " ; " + + "版本号: " + hwVersion + ", " + softVersion + "; " + + "传感器类型: " + sensorType + " ; " + + "上报时间: " + getUptime(); + } + + @Override + public void parseMessageBody() { + workMode = getMessageBody().getString("WORKMODE"); + model = getMessageBody().getString("MODEL"); + hwVersion = getMessageBody().getString("HWVERSION"); + softVersion = getMessageBody().getString("SOFTVERSION"); + sensorType = getMessageBody().getString("SENSORTYPE"); + } +} diff --git a/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java new file mode 100644 index 0000000..e76fc86 --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java @@ -0,0 +1,14 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; + +public interface ISentinelFrameService { + + CasicFrame dataParse(String frame); + + String replyMessage(String deviceCode, String sequence); + + String doBuildCommand(CasicFrame cmd); + + void afterAction(CasicFrame frame); +} diff --git a/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java new file mode 100644 index 0000000..803ff0e --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java @@ -0,0 +1,109 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; +import com.casic.common.CasicFrameBuildFactory; +import com.casic.common.CasicProtocol; +import com.casic.common.general.DataFrame; +import com.casic.common.general.EventFrame; +import com.casic.common.general.ReplyFrame; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.model.DeviceWellView; +import com.casic.dao.service.IDataSentinelOtherService; +import com.casic.dao.service.IDeviceWellViewService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + + +@Service +@Slf4j +public class SentinelFrameServiceImpl implements ISentinelFrameService { + + @Resource + private CasicProtocol protocol; + + @Resource + IDataSentinelOtherService sentinelDataService; + + @Resource + IDeviceWellViewService deviceService; + + public CasicFrame dataParse(String frame) { + // 1. 判断帧结构 + boolean frameValid = protocol.checkFrame(frame); + if (frameValid) { + // 2. 获取帧结构中的关键字段信息 + String deviceId = protocol.getDeviceId(frame); + String deviceType = protocol.getDeviceType(frame); + String messageType = protocol.getMessageType(frame); + String messageBody = protocol.getMessageBody(frame).toUpperCase(); + String uptime = protocol.getUptime(frame); + String sequence = protocol.getMessageSequence(frame); + + String manufacturerCode = protocol.getManufacturerCode(frame); + CasicFrame sentinelFrame = CasicFrameBuildFactory.buildCasicFrame(messageType, manufacturerCode, deviceType); + + if (sentinelFrame != null) { + sentinelFrame.setDeviceCode(deviceId); + sentinelFrame.setUptime(uptime); + sentinelFrame.setMessageType(messageType); + sentinelFrame.setSequence(sequence); + + // 心跳类的消息不解析MessageBody + if (!sentinelFrame.getMessageType().equals("00")) { + sentinelFrame.setMessageBody(protocol.parseMessageBody(messageBody)); + sentinelFrame.parseMessageBody(); + } + + log.info("收到设备消息:{}", sentinelFrame); + return sentinelFrame; + } + } else { + log.error("消息帧解析异常"); + } + + return null; + } + + @Override + public String replyMessage(String deviceCode, String sequence) { + CasicFrame reply = new ReplyFrame(); + reply.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + reply.setDeviceCode(deviceCode); + reply.setSequence(sequence); + reply.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + return protocol.buildReplyFrameStr(reply); + } + + @Override + public String doBuildCommand(CasicFrame cmd) { + return protocol.buildFrameStr(cmd); + } + + @Override + public void afterAction(CasicFrame frame) { + // 数据消息帧 进行存库操作 + if (frame instanceof DataFrame) { + String devCode = frame.getDeviceCode(); + DeviceWellView devWellView = deviceService.getDeviceWellViewByDevCode(devCode); + String wellCode = ""; + if (devWellView != null) { + wellCode = devWellView.getWellCode(); + } + List dataList = ((DataFrame) frame).toDataModelList(); + if (dataList != null) { + for (Serializable item : dataList) { + DataMonitorPipeOther data = (DataMonitorPipeOther) item; + data.setWellCode(wellCode); + sentinelDataService.save(data); + } + } + } + } +} diff --git a/src/main/java/com/casic/tube/controller/TubeDataController.java b/src/main/java/com/casic/tube/controller/TubeDataController.java index 61486c5..4965449 100644 --- a/src/main/java/com/casic/tube/controller/TubeDataController.java +++ b/src/main/java/com/casic/tube/controller/TubeDataController.java @@ -2,8 +2,8 @@ import com.alibaba.fastjson.JSONObject; import com.casic.common.CasicFrame; -import com.casic.tube.frame.ConfigFrame; -import com.casic.tube.service.ITubeDataService; +import com.casic.common.general.ConfigFrame; +import com.casic.tube.service.ITubeFrameService; import com.casic.util.aep.AepCommandSend; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestBody; @@ -21,7 +21,7 @@ public class TubeDataController { @Resource - private ITubeDataService tubeDataService; + private ITubeFrameService frameService; @RequestMapping("/tube/data/recv") public Object dataRecv(@RequestBody Map map) { @@ -42,10 +42,10 @@ String frameStr = new String(baseBytes); // 根据协议进行解析 - CasicFrame frame = tubeDataService.dataParse(frameStr); + CasicFrame frame = frameService.dataParse(frameStr); // 存库 - tubeDataService.afterAction(frame); + frameService.afterAction(frame); retObj.put("code", 200); retObj.put("success", true); @@ -74,7 +74,7 @@ messageBody.put("datas", map.get("cmdList")); cmdFrame.setMessageBody(messageBody); - String frameStr = tubeDataService.doBuildCommand(cmdFrame); + String frameStr = frameService.doBuildCommand(cmdFrame); // TODO-LIST // 这三个参数根据设备编号从数据库中取 diff --git a/src/main/java/com/casic/tube/frame/ConfigFrame.java b/src/main/java/com/casic/tube/frame/ConfigFrame.java deleted file mode 100644 index 883dad6..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigFrame.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigFrame extends CasicFrame { - - public ConfigFrame() { - setSequence("01"); // 默认序号 - setControl("1"); // 默认为不需要分包 - setMessageType("52"); // 消息大类 52 = SetRequest - } -} diff --git a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java b/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java deleted file mode 100644 index a419145..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigResponseFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "03"; - final String MESSAGE_TYPE_STRING = "SetResponse"; - final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "指令序号" + getSequence() + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/DataFrame.java b/src/main/java/com/casic/tube/frame/DataFrame.java deleted file mode 100644 index 97e07b8..0000000 --- a/src/main/java/com/casic/tube/frame/DataFrame.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import com.casic.dao.model.DataTubeOther; - -import java.util.List; - -public class DataFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "02"; - final String MESSAGE_TYPE_STRING = "Data/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "数据消息/管盯"; - - public List dataItemList; - - public List toDataModelList() { - return null; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append(";"); - builder.append("上报时间:").append(getUptime()).append(";"); - for (DataItem dataItem : dataItemList) { - builder.append("["); - builder.append(dataItem); - builder.append("],"); - } - builder.deleteCharAt(builder.length() - 1); - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/DataItem.java b/src/main/java/com/casic/tube/frame/DataItem.java deleted file mode 100644 index 4e9aceb..0000000 --- a/src/main/java/com/casic/tube/frame/DataItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class DataItem { -} diff --git a/src/main/java/com/casic/tube/frame/EventFrame.java b/src/main/java/com/casic/tube/frame/EventFrame.java deleted file mode 100644 index ea800b4..0000000 --- a/src/main/java/com/casic/tube/frame/EventFrame.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -import java.util.List; - -public class EventFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "01"; - final String MESSAGE_TYPE_STRING = "Event/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "事件消息/管盯"; - - public List eventItemList; - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append("; "); - builder.append("上报时间:").append(getUptime()).append("; "); - for (EventItem eventItem : eventItemList) { - builder.append("["); - builder.append(eventItem); - builder.append("],"); - } - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/EventItem.java b/src/main/java/com/casic/tube/frame/EventItem.java deleted file mode 100644 index a1245bf..0000000 --- a/src/main/java/com/casic/tube/frame/EventItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class EventItem { -} diff --git a/src/main/java/com/casic/tube/frame/HeartFrame.java b/src/main/java/com/casic/tube/frame/HeartFrame.java deleted file mode 100644 index af7e7a6..0000000 --- a/src/main/java/com/casic/tube/frame/HeartFrame.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; - -@Data -public class HeartFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "00"; - final String MESSAGE_TYPE_STRING = "OnlineRequest"; - final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/IMEIFrame.java b/src/main/java/com/casic/tube/frame/IMEIFrame.java deleted file mode 100644 index 9420620..0000000 --- a/src/main/java/com/casic/tube/frame/IMEIFrame.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; - -@Data -public class IMEIFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "05"; - final String MESSAGE_TYPE_STRING = "StartupRequest"; - final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; - - String imei; - String iccid; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "IMEI:" + imei + ";" + - "ICCID:" + iccid + - "}"; - } - - @Override - public void parseMessageBody() { - imei = getMessageBody().getString("IMEI"); - iccid = getMessageBody().getString("ICCID"); - } -} diff --git a/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java b/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java index 50e8a2b..47bf4d6 100644 --- a/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java @@ -3,11 +3,12 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.casic.dao.model.DataTubeOther; -import com.casic.tube.frame.DataFrame; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -19,7 +20,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override @@ -43,8 +45,8 @@ } @Override - public List toDataModelList() { - List dataList = new ArrayList<>(); + public List toDataModelList() { + List dataList = new ArrayList<>(); for (DataItem dataItem : dataItemList) { DataTubeOther data = new DataTubeOther(); diff --git a/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java b/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java index 8d09b10..75e94c7 100644 --- a/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.brs; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java b/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java index 9026b4c..2e5c145 100644 --- a/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java @@ -2,14 +2,11 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.casic.common.CasicFrame; -import com.casic.tube.frame.EventFrame; -import com.casic.tube.frame.EventItem; +import com.casic.common.general.EventFrame; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; -import java.util.List; @Data @Slf4j @@ -17,7 +14,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override diff --git a/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java b/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java index 6c8146c..1792320 100644 --- a/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.brs; -import com.casic.tube.frame.EventItem; +import com.casic.common.general.EventItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java b/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java index e6e541c..b05b358 100644 --- a/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java @@ -3,11 +3,12 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.casic.dao.model.DataTubeOther; -import com.casic.tube.frame.DataFrame; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -19,7 +20,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override @@ -43,8 +45,8 @@ } @Override - public List toDataModelList() { - List dataList = new ArrayList<>(); + public List toDataModelList() { + List dataList = new ArrayList<>(); for (DataItem dataItem : dataItemList) { DataTubeOther data = new DataTubeOther(); diff --git a/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java b/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java index 0aa9bab..e875f2a 100644 --- a/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.mhk; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java b/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java index 9aea120..ec2d005 100644 --- a/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java @@ -2,13 +2,11 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.casic.common.CasicFrame; -import com.casic.tube.frame.EventFrame; +import com.casic.common.general.EventFrame; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; -import java.util.List; @Data @Slf4j @@ -16,7 +14,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override diff --git a/src/main/java/com/casic/tube/frame/mhk/EventItemMHK.java b/src/main/java/com/casic/tube/frame/mhk/EventItemMHK.java index 8f6a536..e5ffed6 100644 --- a/src/main/java/com/casic/tube/frame/mhk/EventItemMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/EventItemMHK.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.mhk; -import com.casic.tube.frame.EventItem; +import com.casic.common.general.EventItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/tp/DataFrameHTTP.java b/src/main/java/com/casic/tube/frame/tp/DataFrameHTTP.java index 23df423..69b7c1f 100644 --- a/src/main/java/com/casic/tube/frame/tp/DataFrameHTTP.java +++ b/src/main/java/com/casic/tube/frame/tp/DataFrameHTTP.java @@ -3,11 +3,12 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.casic.dao.model.DataTubeOther; -import com.casic.tube.frame.DataFrame; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -18,6 +19,12 @@ public class DataFrameHTTP extends DataFrame { @Override + public String toString(){ + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); + } + + @Override public void parseMessageBody() { JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); dataItemList = new ArrayList<>(); @@ -40,8 +47,8 @@ } @Override - public List toDataModelList() { - List dataList = new ArrayList<>(); + public List toDataModelList() { + List dataList = new ArrayList<>(); for (DataItem dataItem : dataItemList) { DataTubeOther data = new DataTubeOther(); diff --git a/src/main/java/com/casic/tube/frame/tp/DataItemHTTP.java b/src/main/java/com/casic/tube/frame/tp/DataItemHTTP.java index e5281eb..49d7c87 100644 --- a/src/main/java/com/casic/tube/frame/tp/DataItemHTTP.java +++ b/src/main/java/com/casic/tube/frame/tp/DataItemHTTP.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.tp; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataItem; import lombok.Data; @Data diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java new file mode 100644 index 0000000..95d2bd4 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java @@ -0,0 +1,8 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.DataMonitorPipeOther; + +public interface IDataSentinelOtherService extends IService { + +} diff --git a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java index d6b1200..0290829 100644 --- a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java +++ b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java @@ -1,7 +1,6 @@ package com.casic.dao.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.dao.model.DataTubeOther; import com.casic.dao.model.DeviceWellView; public interface IDeviceWellViewService extends IService { diff --git a/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java new file mode 100644 index 0000000..be34f77 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java @@ -0,0 +1,16 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.BusDeviceMapper; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import org.springframework.stereotype.Service; + +@Service +public class BusDeviceServiceImpl extends ServiceImpl implements IBusDeviceService { + + @Override + public BusDevice getDeviceByCode(String devCode) { + return baseMapper.getOneByDevCode(devCode); + } +} diff --git a/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java new file mode 100644 index 0000000..0db2007 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java @@ -0,0 +1,11 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.DataSentinelOtherMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.service.IDataSentinelOtherService; +import org.springframework.stereotype.Service; + +@Service +public class DataSentinelOtherServiceImpl extends ServiceImpl implements IDataSentinelOtherService { +} diff --git a/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java new file mode 100644 index 0000000..d8c5ef2 --- /dev/null +++ b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java @@ -0,0 +1,111 @@ +package com.casic.protocol; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.CasicProtocol; +import org.springframework.stereotype.Component; + +@Component +public class CasicTubeProtocolImpl implements CasicProtocol { + @Override + public boolean checkFrame(String frame) { + boolean valid = checkFrameHeaderAndTail(frame); + if (valid) { + valid = checkFrameLength(frame); + } + + return valid; + } + + private boolean checkFrameHeaderAndTail(String frame) { + return (frame.substring(0, 2).equalsIgnoreCase("AA")) && + (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); + } + + private boolean checkFrameLength(String frame) { + String lengthStr = frame.substring(4, 7); + int length = Integer.parseInt(lengthStr); + + return frame.length() == length + 9; + } + + @Override + public String getDeviceType(String frame) { + return frame.substring(7, 9); + } + + @Override + public String getDeviceId(String frame) { + return frame.substring(9, 21); + } + + @Override + public String getManufacturerCode(String frame) { + return frame.substring(11, 13); + } + + @Override + public String getMessageType(String frame) { + return frame.substring(21, 23); + } + + @Override + public String getMessageSequence(String frame) { + return frame.substring(23, 25); + } + + @Override + public String getMessageBody(String frame) { + return frame.substring(26, frame.length() - 16); + } + + @Override + public JSONObject parseMessageBody(String messageBody) { + return JSONObject.parseObject(messageBody); + } + + @Override + public String getUptime(String frame) { + return frame.substring(frame.length() - 16, frame.length() - 2); + } + + @Override + public String buildFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append(frame.getMessageBody().toJSONString()); + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } + + @Override + public String buildReplyFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append("00"); // 消息响应类消息 消息体为00 + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/senitnel/controller/SentinelDataController.java b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java new file mode 100644 index 0000000..633c072 --- /dev/null +++ b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java @@ -0,0 +1,120 @@ +package com.casic.senitnel.controller; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.general.ConfigFrame; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import com.casic.senitnel.service.ISentinelFrameService; +import com.casic.util.aep.AepCommandSend; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Base64; +import java.util.Map; + +@Slf4j +@RestController +public class SentinelDataController { + + @Resource + private ISentinelFrameService frameService; + + @Resource + private IBusDeviceService deviceService; + + @RequestMapping("/sentinel/data/recv") + public Object dataRecv(@RequestBody Map map) { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + + JSONObject recvObj = (JSONObject) JSONObject.toJSON(map); + if (recvObj.containsKey("payload")) { + JSONObject payload = recvObj.getJSONObject("payload"); + String value = payload.getString("APPdata"); + + if (value.isEmpty()) { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } else { + byte[] baseBytes = Base64.getDecoder().decode(value); + String frameStr = new String(baseBytes); + + // 根据协议进行解析 + CasicFrame frame = frameService.dataParse(frameStr); + + if (frame != null) { + // 回复响应 + String replyFrameStr = frameService.replyMessage(frame.getDeviceCode(), frame.getSequence()); + + // 从数据库中获取master-api-key 回复响应消息 + BusDevice device = deviceService.getDeviceByCode(frame.getDeviceCode()); + if (device != null && StringUtils.isNotBlank(device.getMasterApiKey())) { + String masterApiKey = device.getMasterApiKey(); + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + + try { + int code = aepCommandSend.handleAndReply(replyFrameStr); + } catch (Exception ex) { + log.error("向设备回复响应异常:{}", ex.getMessage()); + } + } + + // 存库 + frameService.afterAction(frame); + } + + retObj.put("code", 200); + retObj.put("success", true); + } + } else { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } + + return retObj; + } + + @RequestMapping("/sentinel/config/send") + public Object configSend(@RequestBody Map map) throws Exception { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + CasicFrame cmdFrame = new ConfigFrame(); + cmdFrame.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + cmdFrame.setDeviceCode((String) map.get("devCode")); + cmdFrame.setSequence("01"); + cmdFrame.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + JSONObject messageBody = new JSONObject(); + messageBody.put("datas", map.get("cmdList")); + cmdFrame.setMessageBody(messageBody); + + String frameStr = frameService.doBuildCommand(cmdFrame); + + // TODO-LIST + // 这三个参数根据设备编号从数据库中取 + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + String masterApiKey = (String) map.get("masterApiKey"); + + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + int code = aepCommandSend.handleAndReply(frameStr); + + retObj.put("code", 200); + retObj.put("success", true); + retObj.put("AEPRetCode", code); + return retObj; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java new file mode 100644 index 0000000..368af03 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java @@ -0,0 +1,82 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; +import com.casic.dao.model.DataMonitorPipeOther; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class DataFrameNCX extends DataFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + dataItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + DataItemNCX dataItem = new DataItemNCX(); + + dataItem.setLenL(dataObj.getString("LENGL")); + dataItem.setLenR(dataObj.getString("LENGR")); + dataItem.setBat(dataObj.getString("BAT")); + dataItem.setCh4L(dataObj.getString("CH4L")); + dataItem.setCh4R(dataObj.getString("CH4R")); + dataItem.setSlope(dataObj.getString("SLOPING")); + dataItem.setDestroy(dataObj.getString("DESTROY")); + dataItem.setLeak(dataObj.getString("LEAK")); + dataItem.setDiscL(dataObj.getString("DISCL")); + dataItem.setDiscR(dataObj.getString("DISCR")); + dataItem.setVibL(dataObj.getString("VIBL")); + dataItem.setVibR(dataObj.getString("VIBR")); + dataItem.setTime(dataObj.getString("UPTIME")); + + dataItemList.add(dataItem); + } + } + + @Override + public List toDataModelList() { + List dataList = new ArrayList<>(); + for (DataItem dataItem : dataItemList) { + DataMonitorPipeOther data = new DataMonitorPipeOther(); + + data.setDevcode(getDeviceCode()); + data.setLeftLength(((DataItemNCX)dataItem).getLenL()); + data.setRightLength(((DataItemNCX)dataItem).getLenR()); + data.setLeftGas(((DataItemNCX)dataItem).getCh4L()); + data.setRightGas(((DataItemNCX)dataItem).getCh4R()); + data.setVbat(((DataItemNCX)dataItem).getBat()); + data.setPipeInclineAlarm(((DataItemNCX)dataItem).getSlope()); + data.setPipeBreakAlarm(((DataItemNCX)dataItem).getDestroy()); + data.setGasAlarm(((DataItemNCX)dataItem).getLeak()); + data.setLeftOfflineAlarm(((DataItemNCX)dataItem).getDiscL()); + data.setRightOfflineAlarm(((DataItemNCX)dataItem).getDiscR()); + data.setLeftVibrateAlarm(((DataItemNCX)dataItem).getVibL()); + data.setRightVibrateAlarm(((DataItemNCX)dataItem).getVibR()); + data.setUptime(LocalDateTime.parse(((DataItemNCX)dataItem).getTime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 采集时间 + data.setLogtime(LocalDateTime.parse(getUptime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 上报时间 + + dataList.add(data); + } + + return dataList; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java new file mode 100644 index 0000000..372ac73 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java @@ -0,0 +1,31 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.DataItem; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class DataItemNCX extends DataItem { + String lenL; // 左侧指示带长度 + String lenR; // 右侧指示带长度 + String ch4L; // 左侧甲烷浓度值 + String ch4R; // 右侧甲烷浓度值 + String bat; // 电池电压 + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String spare; // 备用 + String time; // 采集时间 + + @Override + public String toString() { + return "气体浓度值:" + "(" + ch4L + "," + ch4R + ")" + "%LEL;" + + "电池电压值:" + bat + "v;" + + "采样时间:" + time; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java new file mode 100644 index 0000000..b3bbcf4 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java @@ -0,0 +1,43 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.EventFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class EventFrameNCX extends EventFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + eventItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + EventItemNCX eventItem = new EventItemNCX(); + + eventItem.setSlope(dataObj.getString("SLOPING")); + eventItem.setDestroy(dataObj.getString("DESTROY")); + eventItem.setLeak(dataObj.getString("LEAK")); + eventItem.setDiscL(dataObj.getString("DISCL")); + eventItem.setDiscR(dataObj.getString("DISCR")); + eventItem.setVibL(dataObj.getString("VIBL")); + eventItem.setVibR(dataObj.getString("VIBR")); + eventItem.setTime(dataObj.getString("UPTIME")); + + eventItemList.add(eventItem); + } + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java new file mode 100644 index 0000000..1a560d0 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java @@ -0,0 +1,49 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.EventItem; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.commons.lang3.StringUtils; + +@EqualsAndHashCode(callSuper = true) +@Data +public class EventItemNCX extends EventItem { + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String time; // 采集时间 + + @Override + public String toString() { + String str = ""; + if (StringUtils.isNotBlank(slope) && slope.equalsIgnoreCase("1")) { + str += "[倾斜报警]"; + } + if (StringUtils.isNotBlank(destroy) && destroy.equalsIgnoreCase("1")) { + str += "[破坏报警]"; + } + if (StringUtils.isNotBlank(leak) && leak.equalsIgnoreCase("1")) { + str += "[甲烷泄漏报警]"; + } + if (StringUtils.isNotBlank(discL) && discL.equalsIgnoreCase("1")) { + str += "[左侧断线报警]"; + } + if (StringUtils.isNotBlank(discR) && discR.equalsIgnoreCase("1")) { + str += "[右侧断线报警]"; + } + if (StringUtils.isNotBlank(vibL) && vibL.equalsIgnoreCase("1")) { + str += "[左侧振动报警]"; + } + if (StringUtils.isNotBlank(vibR) && vibR.equalsIgnoreCase("1")) { + str += "[右侧振动报警]"; + } + str += "采样时间:" + time; + + return str; + + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java new file mode 100644 index 0000000..343c4d6 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java @@ -0,0 +1,37 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class InfoFrameNCX extends CasicFrame { + + String workMode; + String model; + String hwVersion; + String softVersion; + String sensorType; + + @Override + public String toString() { + return "设备编号: " + getDeviceCode() + "; " + + "设备工作模式: " + workMode + " ; " + + "设备型号: " + model + " ; " + + "版本号: " + hwVersion + ", " + softVersion + "; " + + "传感器类型: " + sensorType + " ; " + + "上报时间: " + getUptime(); + } + + @Override + public void parseMessageBody() { + workMode = getMessageBody().getString("WORKMODE"); + model = getMessageBody().getString("MODEL"); + hwVersion = getMessageBody().getString("HWVERSION"); + softVersion = getMessageBody().getString("SOFTVERSION"); + sensorType = getMessageBody().getString("SENSORTYPE"); + } +} diff --git a/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java new file mode 100644 index 0000000..e76fc86 --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java @@ -0,0 +1,14 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; + +public interface ISentinelFrameService { + + CasicFrame dataParse(String frame); + + String replyMessage(String deviceCode, String sequence); + + String doBuildCommand(CasicFrame cmd); + + void afterAction(CasicFrame frame); +} diff --git a/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java new file mode 100644 index 0000000..803ff0e --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java @@ -0,0 +1,109 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; +import com.casic.common.CasicFrameBuildFactory; +import com.casic.common.CasicProtocol; +import com.casic.common.general.DataFrame; +import com.casic.common.general.EventFrame; +import com.casic.common.general.ReplyFrame; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.model.DeviceWellView; +import com.casic.dao.service.IDataSentinelOtherService; +import com.casic.dao.service.IDeviceWellViewService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + + +@Service +@Slf4j +public class SentinelFrameServiceImpl implements ISentinelFrameService { + + @Resource + private CasicProtocol protocol; + + @Resource + IDataSentinelOtherService sentinelDataService; + + @Resource + IDeviceWellViewService deviceService; + + public CasicFrame dataParse(String frame) { + // 1. 判断帧结构 + boolean frameValid = protocol.checkFrame(frame); + if (frameValid) { + // 2. 获取帧结构中的关键字段信息 + String deviceId = protocol.getDeviceId(frame); + String deviceType = protocol.getDeviceType(frame); + String messageType = protocol.getMessageType(frame); + String messageBody = protocol.getMessageBody(frame).toUpperCase(); + String uptime = protocol.getUptime(frame); + String sequence = protocol.getMessageSequence(frame); + + String manufacturerCode = protocol.getManufacturerCode(frame); + CasicFrame sentinelFrame = CasicFrameBuildFactory.buildCasicFrame(messageType, manufacturerCode, deviceType); + + if (sentinelFrame != null) { + sentinelFrame.setDeviceCode(deviceId); + sentinelFrame.setUptime(uptime); + sentinelFrame.setMessageType(messageType); + sentinelFrame.setSequence(sequence); + + // 心跳类的消息不解析MessageBody + if (!sentinelFrame.getMessageType().equals("00")) { + sentinelFrame.setMessageBody(protocol.parseMessageBody(messageBody)); + sentinelFrame.parseMessageBody(); + } + + log.info("收到设备消息:{}", sentinelFrame); + return sentinelFrame; + } + } else { + log.error("消息帧解析异常"); + } + + return null; + } + + @Override + public String replyMessage(String deviceCode, String sequence) { + CasicFrame reply = new ReplyFrame(); + reply.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + reply.setDeviceCode(deviceCode); + reply.setSequence(sequence); + reply.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + return protocol.buildReplyFrameStr(reply); + } + + @Override + public String doBuildCommand(CasicFrame cmd) { + return protocol.buildFrameStr(cmd); + } + + @Override + public void afterAction(CasicFrame frame) { + // 数据消息帧 进行存库操作 + if (frame instanceof DataFrame) { + String devCode = frame.getDeviceCode(); + DeviceWellView devWellView = deviceService.getDeviceWellViewByDevCode(devCode); + String wellCode = ""; + if (devWellView != null) { + wellCode = devWellView.getWellCode(); + } + List dataList = ((DataFrame) frame).toDataModelList(); + if (dataList != null) { + for (Serializable item : dataList) { + DataMonitorPipeOther data = (DataMonitorPipeOther) item; + data.setWellCode(wellCode); + sentinelDataService.save(data); + } + } + } + } +} diff --git a/src/main/java/com/casic/tube/controller/TubeDataController.java b/src/main/java/com/casic/tube/controller/TubeDataController.java index 61486c5..4965449 100644 --- a/src/main/java/com/casic/tube/controller/TubeDataController.java +++ b/src/main/java/com/casic/tube/controller/TubeDataController.java @@ -2,8 +2,8 @@ import com.alibaba.fastjson.JSONObject; import com.casic.common.CasicFrame; -import com.casic.tube.frame.ConfigFrame; -import com.casic.tube.service.ITubeDataService; +import com.casic.common.general.ConfigFrame; +import com.casic.tube.service.ITubeFrameService; import com.casic.util.aep.AepCommandSend; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestBody; @@ -21,7 +21,7 @@ public class TubeDataController { @Resource - private ITubeDataService tubeDataService; + private ITubeFrameService frameService; @RequestMapping("/tube/data/recv") public Object dataRecv(@RequestBody Map map) { @@ -42,10 +42,10 @@ String frameStr = new String(baseBytes); // 根据协议进行解析 - CasicFrame frame = tubeDataService.dataParse(frameStr); + CasicFrame frame = frameService.dataParse(frameStr); // 存库 - tubeDataService.afterAction(frame); + frameService.afterAction(frame); retObj.put("code", 200); retObj.put("success", true); @@ -74,7 +74,7 @@ messageBody.put("datas", map.get("cmdList")); cmdFrame.setMessageBody(messageBody); - String frameStr = tubeDataService.doBuildCommand(cmdFrame); + String frameStr = frameService.doBuildCommand(cmdFrame); // TODO-LIST // 这三个参数根据设备编号从数据库中取 diff --git a/src/main/java/com/casic/tube/frame/ConfigFrame.java b/src/main/java/com/casic/tube/frame/ConfigFrame.java deleted file mode 100644 index 883dad6..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigFrame.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigFrame extends CasicFrame { - - public ConfigFrame() { - setSequence("01"); // 默认序号 - setControl("1"); // 默认为不需要分包 - setMessageType("52"); // 消息大类 52 = SetRequest - } -} diff --git a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java b/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java deleted file mode 100644 index a419145..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigResponseFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "03"; - final String MESSAGE_TYPE_STRING = "SetResponse"; - final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "指令序号" + getSequence() + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/DataFrame.java b/src/main/java/com/casic/tube/frame/DataFrame.java deleted file mode 100644 index 97e07b8..0000000 --- a/src/main/java/com/casic/tube/frame/DataFrame.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import com.casic.dao.model.DataTubeOther; - -import java.util.List; - -public class DataFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "02"; - final String MESSAGE_TYPE_STRING = "Data/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "数据消息/管盯"; - - public List dataItemList; - - public List toDataModelList() { - return null; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append(";"); - builder.append("上报时间:").append(getUptime()).append(";"); - for (DataItem dataItem : dataItemList) { - builder.append("["); - builder.append(dataItem); - builder.append("],"); - } - builder.deleteCharAt(builder.length() - 1); - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/DataItem.java b/src/main/java/com/casic/tube/frame/DataItem.java deleted file mode 100644 index 4e9aceb..0000000 --- a/src/main/java/com/casic/tube/frame/DataItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class DataItem { -} diff --git a/src/main/java/com/casic/tube/frame/EventFrame.java b/src/main/java/com/casic/tube/frame/EventFrame.java deleted file mode 100644 index ea800b4..0000000 --- a/src/main/java/com/casic/tube/frame/EventFrame.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -import java.util.List; - -public class EventFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "01"; - final String MESSAGE_TYPE_STRING = "Event/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "事件消息/管盯"; - - public List eventItemList; - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append("; "); - builder.append("上报时间:").append(getUptime()).append("; "); - for (EventItem eventItem : eventItemList) { - builder.append("["); - builder.append(eventItem); - builder.append("],"); - } - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/EventItem.java b/src/main/java/com/casic/tube/frame/EventItem.java deleted file mode 100644 index a1245bf..0000000 --- a/src/main/java/com/casic/tube/frame/EventItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class EventItem { -} diff --git a/src/main/java/com/casic/tube/frame/HeartFrame.java b/src/main/java/com/casic/tube/frame/HeartFrame.java deleted file mode 100644 index af7e7a6..0000000 --- a/src/main/java/com/casic/tube/frame/HeartFrame.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; - -@Data -public class HeartFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "00"; - final String MESSAGE_TYPE_STRING = "OnlineRequest"; - final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/IMEIFrame.java b/src/main/java/com/casic/tube/frame/IMEIFrame.java deleted file mode 100644 index 9420620..0000000 --- a/src/main/java/com/casic/tube/frame/IMEIFrame.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; - -@Data -public class IMEIFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "05"; - final String MESSAGE_TYPE_STRING = "StartupRequest"; - final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; - - String imei; - String iccid; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "IMEI:" + imei + ";" + - "ICCID:" + iccid + - "}"; - } - - @Override - public void parseMessageBody() { - imei = getMessageBody().getString("IMEI"); - iccid = getMessageBody().getString("ICCID"); - } -} diff --git a/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java b/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java index 50e8a2b..47bf4d6 100644 --- a/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java @@ -3,11 +3,12 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.casic.dao.model.DataTubeOther; -import com.casic.tube.frame.DataFrame; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -19,7 +20,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override @@ -43,8 +45,8 @@ } @Override - public List toDataModelList() { - List dataList = new ArrayList<>(); + public List toDataModelList() { + List dataList = new ArrayList<>(); for (DataItem dataItem : dataItemList) { DataTubeOther data = new DataTubeOther(); diff --git a/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java b/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java index 8d09b10..75e94c7 100644 --- a/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.brs; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java b/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java index 9026b4c..2e5c145 100644 --- a/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java @@ -2,14 +2,11 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.casic.common.CasicFrame; -import com.casic.tube.frame.EventFrame; -import com.casic.tube.frame.EventItem; +import com.casic.common.general.EventFrame; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; -import java.util.List; @Data @Slf4j @@ -17,7 +14,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override diff --git a/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java b/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java index 6c8146c..1792320 100644 --- a/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.brs; -import com.casic.tube.frame.EventItem; +import com.casic.common.general.EventItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java b/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java index e6e541c..b05b358 100644 --- a/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java @@ -3,11 +3,12 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.casic.dao.model.DataTubeOther; -import com.casic.tube.frame.DataFrame; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -19,7 +20,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override @@ -43,8 +45,8 @@ } @Override - public List toDataModelList() { - List dataList = new ArrayList<>(); + public List toDataModelList() { + List dataList = new ArrayList<>(); for (DataItem dataItem : dataItemList) { DataTubeOther data = new DataTubeOther(); diff --git a/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java b/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java index 0aa9bab..e875f2a 100644 --- a/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.mhk; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java b/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java index 9aea120..ec2d005 100644 --- a/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java @@ -2,13 +2,11 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.casic.common.CasicFrame; -import com.casic.tube.frame.EventFrame; +import com.casic.common.general.EventFrame; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; -import java.util.List; @Data @Slf4j @@ -16,7 +14,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override diff --git a/src/main/java/com/casic/tube/frame/mhk/EventItemMHK.java b/src/main/java/com/casic/tube/frame/mhk/EventItemMHK.java index 8f6a536..e5ffed6 100644 --- a/src/main/java/com/casic/tube/frame/mhk/EventItemMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/EventItemMHK.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.mhk; -import com.casic.tube.frame.EventItem; +import com.casic.common.general.EventItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/tp/DataFrameHTTP.java b/src/main/java/com/casic/tube/frame/tp/DataFrameHTTP.java index 23df423..69b7c1f 100644 --- a/src/main/java/com/casic/tube/frame/tp/DataFrameHTTP.java +++ b/src/main/java/com/casic/tube/frame/tp/DataFrameHTTP.java @@ -3,11 +3,12 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.casic.dao.model.DataTubeOther; -import com.casic.tube.frame.DataFrame; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -18,6 +19,12 @@ public class DataFrameHTTP extends DataFrame { @Override + public String toString(){ + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); + } + + @Override public void parseMessageBody() { JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); dataItemList = new ArrayList<>(); @@ -40,8 +47,8 @@ } @Override - public List toDataModelList() { - List dataList = new ArrayList<>(); + public List toDataModelList() { + List dataList = new ArrayList<>(); for (DataItem dataItem : dataItemList) { DataTubeOther data = new DataTubeOther(); diff --git a/src/main/java/com/casic/tube/frame/tp/DataItemHTTP.java b/src/main/java/com/casic/tube/frame/tp/DataItemHTTP.java index e5281eb..49d7c87 100644 --- a/src/main/java/com/casic/tube/frame/tp/DataItemHTTP.java +++ b/src/main/java/com/casic/tube/frame/tp/DataItemHTTP.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.tp; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/tube/protocol/CasicTubeProtocolImpl.java deleted file mode 100644 index 4fdd78c..0000000 --- a/src/main/java/com/casic/tube/protocol/CasicTubeProtocolImpl.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.casic.tube.protocol; - -import com.alibaba.fastjson.JSONObject; -import com.casic.common.CasicFrame; -import com.casic.common.CasicProtocol; -import org.springframework.stereotype.Component; - -@Component -public class CasicTubeProtocolImpl implements CasicProtocol { - @Override - public boolean checkFrame(String frame) { - boolean valid = checkFrameHeaderAndTail(frame); - if (valid) { - valid = checkFrameLength(frame); - } - - return valid; - } - - private boolean checkFrameHeaderAndTail(String frame) { - return (frame.substring(0, 2).equalsIgnoreCase("AA")) && - (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); - } - - private boolean checkFrameLength(String frame) { - String lengthStr = frame.substring(4, 7); - int length = Integer.parseInt(lengthStr); - - return frame.length() == length + 9; - } - - @Override - public String getDeviceType(String frame) { - return frame.substring(7, 9); - } - - @Override - public String getDeviceId(String frame) { - return frame.substring(9, 21); - } - - @Override - public String getManufacturerCode(String frame) { - return frame.substring(11, 13); - } - - @Override - public String getMessageType(String frame) { - return frame.substring(21, 23); - } - - @Override - public String getMessageBody(String frame) { - return frame.substring(26, frame.length() - 16); - } - - @Override - public JSONObject parseMessageBody(String messageBody) { - return JSONObject.parseObject(messageBody); - } - - @Override - public String getUptime(String frame) { - return frame.substring(frame.length() - 16, frame.length() - 2); - } - - @Override - public String buildFrameStr(CasicFrame frame) { - StringBuilder builder = new StringBuilder(); - - builder.append(frame.getDeviceType()); - builder.append(frame.getDeviceCode()); - builder.append(frame.getMessageType()); - builder.append(frame.getSequence()); - builder.append(frame.getControl()); - builder.append(frame.getMessageBody().toJSONString()); - builder.append(frame.getUptime()); - - builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 - builder.insert(0, frame.getVersion()); - builder.insert(0, frame.getHEADER()); - builder.append(frame.getTAIL()); - - return builder.toString(); - } -} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java new file mode 100644 index 0000000..95d2bd4 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java @@ -0,0 +1,8 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.DataMonitorPipeOther; + +public interface IDataSentinelOtherService extends IService { + +} diff --git a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java index d6b1200..0290829 100644 --- a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java +++ b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java @@ -1,7 +1,6 @@ package com.casic.dao.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.dao.model.DataTubeOther; import com.casic.dao.model.DeviceWellView; public interface IDeviceWellViewService extends IService { diff --git a/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java new file mode 100644 index 0000000..be34f77 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java @@ -0,0 +1,16 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.BusDeviceMapper; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import org.springframework.stereotype.Service; + +@Service +public class BusDeviceServiceImpl extends ServiceImpl implements IBusDeviceService { + + @Override + public BusDevice getDeviceByCode(String devCode) { + return baseMapper.getOneByDevCode(devCode); + } +} diff --git a/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java new file mode 100644 index 0000000..0db2007 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java @@ -0,0 +1,11 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.DataSentinelOtherMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.service.IDataSentinelOtherService; +import org.springframework.stereotype.Service; + +@Service +public class DataSentinelOtherServiceImpl extends ServiceImpl implements IDataSentinelOtherService { +} diff --git a/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java new file mode 100644 index 0000000..d8c5ef2 --- /dev/null +++ b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java @@ -0,0 +1,111 @@ +package com.casic.protocol; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.CasicProtocol; +import org.springframework.stereotype.Component; + +@Component +public class CasicTubeProtocolImpl implements CasicProtocol { + @Override + public boolean checkFrame(String frame) { + boolean valid = checkFrameHeaderAndTail(frame); + if (valid) { + valid = checkFrameLength(frame); + } + + return valid; + } + + private boolean checkFrameHeaderAndTail(String frame) { + return (frame.substring(0, 2).equalsIgnoreCase("AA")) && + (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); + } + + private boolean checkFrameLength(String frame) { + String lengthStr = frame.substring(4, 7); + int length = Integer.parseInt(lengthStr); + + return frame.length() == length + 9; + } + + @Override + public String getDeviceType(String frame) { + return frame.substring(7, 9); + } + + @Override + public String getDeviceId(String frame) { + return frame.substring(9, 21); + } + + @Override + public String getManufacturerCode(String frame) { + return frame.substring(11, 13); + } + + @Override + public String getMessageType(String frame) { + return frame.substring(21, 23); + } + + @Override + public String getMessageSequence(String frame) { + return frame.substring(23, 25); + } + + @Override + public String getMessageBody(String frame) { + return frame.substring(26, frame.length() - 16); + } + + @Override + public JSONObject parseMessageBody(String messageBody) { + return JSONObject.parseObject(messageBody); + } + + @Override + public String getUptime(String frame) { + return frame.substring(frame.length() - 16, frame.length() - 2); + } + + @Override + public String buildFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append(frame.getMessageBody().toJSONString()); + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } + + @Override + public String buildReplyFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append("00"); // 消息响应类消息 消息体为00 + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/senitnel/controller/SentinelDataController.java b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java new file mode 100644 index 0000000..633c072 --- /dev/null +++ b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java @@ -0,0 +1,120 @@ +package com.casic.senitnel.controller; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.general.ConfigFrame; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import com.casic.senitnel.service.ISentinelFrameService; +import com.casic.util.aep.AepCommandSend; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Base64; +import java.util.Map; + +@Slf4j +@RestController +public class SentinelDataController { + + @Resource + private ISentinelFrameService frameService; + + @Resource + private IBusDeviceService deviceService; + + @RequestMapping("/sentinel/data/recv") + public Object dataRecv(@RequestBody Map map) { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + + JSONObject recvObj = (JSONObject) JSONObject.toJSON(map); + if (recvObj.containsKey("payload")) { + JSONObject payload = recvObj.getJSONObject("payload"); + String value = payload.getString("APPdata"); + + if (value.isEmpty()) { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } else { + byte[] baseBytes = Base64.getDecoder().decode(value); + String frameStr = new String(baseBytes); + + // 根据协议进行解析 + CasicFrame frame = frameService.dataParse(frameStr); + + if (frame != null) { + // 回复响应 + String replyFrameStr = frameService.replyMessage(frame.getDeviceCode(), frame.getSequence()); + + // 从数据库中获取master-api-key 回复响应消息 + BusDevice device = deviceService.getDeviceByCode(frame.getDeviceCode()); + if (device != null && StringUtils.isNotBlank(device.getMasterApiKey())) { + String masterApiKey = device.getMasterApiKey(); + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + + try { + int code = aepCommandSend.handleAndReply(replyFrameStr); + } catch (Exception ex) { + log.error("向设备回复响应异常:{}", ex.getMessage()); + } + } + + // 存库 + frameService.afterAction(frame); + } + + retObj.put("code", 200); + retObj.put("success", true); + } + } else { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } + + return retObj; + } + + @RequestMapping("/sentinel/config/send") + public Object configSend(@RequestBody Map map) throws Exception { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + CasicFrame cmdFrame = new ConfigFrame(); + cmdFrame.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + cmdFrame.setDeviceCode((String) map.get("devCode")); + cmdFrame.setSequence("01"); + cmdFrame.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + JSONObject messageBody = new JSONObject(); + messageBody.put("datas", map.get("cmdList")); + cmdFrame.setMessageBody(messageBody); + + String frameStr = frameService.doBuildCommand(cmdFrame); + + // TODO-LIST + // 这三个参数根据设备编号从数据库中取 + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + String masterApiKey = (String) map.get("masterApiKey"); + + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + int code = aepCommandSend.handleAndReply(frameStr); + + retObj.put("code", 200); + retObj.put("success", true); + retObj.put("AEPRetCode", code); + return retObj; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java new file mode 100644 index 0000000..368af03 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java @@ -0,0 +1,82 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; +import com.casic.dao.model.DataMonitorPipeOther; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class DataFrameNCX extends DataFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + dataItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + DataItemNCX dataItem = new DataItemNCX(); + + dataItem.setLenL(dataObj.getString("LENGL")); + dataItem.setLenR(dataObj.getString("LENGR")); + dataItem.setBat(dataObj.getString("BAT")); + dataItem.setCh4L(dataObj.getString("CH4L")); + dataItem.setCh4R(dataObj.getString("CH4R")); + dataItem.setSlope(dataObj.getString("SLOPING")); + dataItem.setDestroy(dataObj.getString("DESTROY")); + dataItem.setLeak(dataObj.getString("LEAK")); + dataItem.setDiscL(dataObj.getString("DISCL")); + dataItem.setDiscR(dataObj.getString("DISCR")); + dataItem.setVibL(dataObj.getString("VIBL")); + dataItem.setVibR(dataObj.getString("VIBR")); + dataItem.setTime(dataObj.getString("UPTIME")); + + dataItemList.add(dataItem); + } + } + + @Override + public List toDataModelList() { + List dataList = new ArrayList<>(); + for (DataItem dataItem : dataItemList) { + DataMonitorPipeOther data = new DataMonitorPipeOther(); + + data.setDevcode(getDeviceCode()); + data.setLeftLength(((DataItemNCX)dataItem).getLenL()); + data.setRightLength(((DataItemNCX)dataItem).getLenR()); + data.setLeftGas(((DataItemNCX)dataItem).getCh4L()); + data.setRightGas(((DataItemNCX)dataItem).getCh4R()); + data.setVbat(((DataItemNCX)dataItem).getBat()); + data.setPipeInclineAlarm(((DataItemNCX)dataItem).getSlope()); + data.setPipeBreakAlarm(((DataItemNCX)dataItem).getDestroy()); + data.setGasAlarm(((DataItemNCX)dataItem).getLeak()); + data.setLeftOfflineAlarm(((DataItemNCX)dataItem).getDiscL()); + data.setRightOfflineAlarm(((DataItemNCX)dataItem).getDiscR()); + data.setLeftVibrateAlarm(((DataItemNCX)dataItem).getVibL()); + data.setRightVibrateAlarm(((DataItemNCX)dataItem).getVibR()); + data.setUptime(LocalDateTime.parse(((DataItemNCX)dataItem).getTime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 采集时间 + data.setLogtime(LocalDateTime.parse(getUptime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 上报时间 + + dataList.add(data); + } + + return dataList; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java new file mode 100644 index 0000000..372ac73 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java @@ -0,0 +1,31 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.DataItem; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class DataItemNCX extends DataItem { + String lenL; // 左侧指示带长度 + String lenR; // 右侧指示带长度 + String ch4L; // 左侧甲烷浓度值 + String ch4R; // 右侧甲烷浓度值 + String bat; // 电池电压 + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String spare; // 备用 + String time; // 采集时间 + + @Override + public String toString() { + return "气体浓度值:" + "(" + ch4L + "," + ch4R + ")" + "%LEL;" + + "电池电压值:" + bat + "v;" + + "采样时间:" + time; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java new file mode 100644 index 0000000..b3bbcf4 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java @@ -0,0 +1,43 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.EventFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class EventFrameNCX extends EventFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + eventItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + EventItemNCX eventItem = new EventItemNCX(); + + eventItem.setSlope(dataObj.getString("SLOPING")); + eventItem.setDestroy(dataObj.getString("DESTROY")); + eventItem.setLeak(dataObj.getString("LEAK")); + eventItem.setDiscL(dataObj.getString("DISCL")); + eventItem.setDiscR(dataObj.getString("DISCR")); + eventItem.setVibL(dataObj.getString("VIBL")); + eventItem.setVibR(dataObj.getString("VIBR")); + eventItem.setTime(dataObj.getString("UPTIME")); + + eventItemList.add(eventItem); + } + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java new file mode 100644 index 0000000..1a560d0 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java @@ -0,0 +1,49 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.EventItem; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.commons.lang3.StringUtils; + +@EqualsAndHashCode(callSuper = true) +@Data +public class EventItemNCX extends EventItem { + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String time; // 采集时间 + + @Override + public String toString() { + String str = ""; + if (StringUtils.isNotBlank(slope) && slope.equalsIgnoreCase("1")) { + str += "[倾斜报警]"; + } + if (StringUtils.isNotBlank(destroy) && destroy.equalsIgnoreCase("1")) { + str += "[破坏报警]"; + } + if (StringUtils.isNotBlank(leak) && leak.equalsIgnoreCase("1")) { + str += "[甲烷泄漏报警]"; + } + if (StringUtils.isNotBlank(discL) && discL.equalsIgnoreCase("1")) { + str += "[左侧断线报警]"; + } + if (StringUtils.isNotBlank(discR) && discR.equalsIgnoreCase("1")) { + str += "[右侧断线报警]"; + } + if (StringUtils.isNotBlank(vibL) && vibL.equalsIgnoreCase("1")) { + str += "[左侧振动报警]"; + } + if (StringUtils.isNotBlank(vibR) && vibR.equalsIgnoreCase("1")) { + str += "[右侧振动报警]"; + } + str += "采样时间:" + time; + + return str; + + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java new file mode 100644 index 0000000..343c4d6 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java @@ -0,0 +1,37 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class InfoFrameNCX extends CasicFrame { + + String workMode; + String model; + String hwVersion; + String softVersion; + String sensorType; + + @Override + public String toString() { + return "设备编号: " + getDeviceCode() + "; " + + "设备工作模式: " + workMode + " ; " + + "设备型号: " + model + " ; " + + "版本号: " + hwVersion + ", " + softVersion + "; " + + "传感器类型: " + sensorType + " ; " + + "上报时间: " + getUptime(); + } + + @Override + public void parseMessageBody() { + workMode = getMessageBody().getString("WORKMODE"); + model = getMessageBody().getString("MODEL"); + hwVersion = getMessageBody().getString("HWVERSION"); + softVersion = getMessageBody().getString("SOFTVERSION"); + sensorType = getMessageBody().getString("SENSORTYPE"); + } +} diff --git a/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java new file mode 100644 index 0000000..e76fc86 --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java @@ -0,0 +1,14 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; + +public interface ISentinelFrameService { + + CasicFrame dataParse(String frame); + + String replyMessage(String deviceCode, String sequence); + + String doBuildCommand(CasicFrame cmd); + + void afterAction(CasicFrame frame); +} diff --git a/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java new file mode 100644 index 0000000..803ff0e --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java @@ -0,0 +1,109 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; +import com.casic.common.CasicFrameBuildFactory; +import com.casic.common.CasicProtocol; +import com.casic.common.general.DataFrame; +import com.casic.common.general.EventFrame; +import com.casic.common.general.ReplyFrame; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.model.DeviceWellView; +import com.casic.dao.service.IDataSentinelOtherService; +import com.casic.dao.service.IDeviceWellViewService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + + +@Service +@Slf4j +public class SentinelFrameServiceImpl implements ISentinelFrameService { + + @Resource + private CasicProtocol protocol; + + @Resource + IDataSentinelOtherService sentinelDataService; + + @Resource + IDeviceWellViewService deviceService; + + public CasicFrame dataParse(String frame) { + // 1. 判断帧结构 + boolean frameValid = protocol.checkFrame(frame); + if (frameValid) { + // 2. 获取帧结构中的关键字段信息 + String deviceId = protocol.getDeviceId(frame); + String deviceType = protocol.getDeviceType(frame); + String messageType = protocol.getMessageType(frame); + String messageBody = protocol.getMessageBody(frame).toUpperCase(); + String uptime = protocol.getUptime(frame); + String sequence = protocol.getMessageSequence(frame); + + String manufacturerCode = protocol.getManufacturerCode(frame); + CasicFrame sentinelFrame = CasicFrameBuildFactory.buildCasicFrame(messageType, manufacturerCode, deviceType); + + if (sentinelFrame != null) { + sentinelFrame.setDeviceCode(deviceId); + sentinelFrame.setUptime(uptime); + sentinelFrame.setMessageType(messageType); + sentinelFrame.setSequence(sequence); + + // 心跳类的消息不解析MessageBody + if (!sentinelFrame.getMessageType().equals("00")) { + sentinelFrame.setMessageBody(protocol.parseMessageBody(messageBody)); + sentinelFrame.parseMessageBody(); + } + + log.info("收到设备消息:{}", sentinelFrame); + return sentinelFrame; + } + } else { + log.error("消息帧解析异常"); + } + + return null; + } + + @Override + public String replyMessage(String deviceCode, String sequence) { + CasicFrame reply = new ReplyFrame(); + reply.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + reply.setDeviceCode(deviceCode); + reply.setSequence(sequence); + reply.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + return protocol.buildReplyFrameStr(reply); + } + + @Override + public String doBuildCommand(CasicFrame cmd) { + return protocol.buildFrameStr(cmd); + } + + @Override + public void afterAction(CasicFrame frame) { + // 数据消息帧 进行存库操作 + if (frame instanceof DataFrame) { + String devCode = frame.getDeviceCode(); + DeviceWellView devWellView = deviceService.getDeviceWellViewByDevCode(devCode); + String wellCode = ""; + if (devWellView != null) { + wellCode = devWellView.getWellCode(); + } + List dataList = ((DataFrame) frame).toDataModelList(); + if (dataList != null) { + for (Serializable item : dataList) { + DataMonitorPipeOther data = (DataMonitorPipeOther) item; + data.setWellCode(wellCode); + sentinelDataService.save(data); + } + } + } + } +} diff --git a/src/main/java/com/casic/tube/controller/TubeDataController.java b/src/main/java/com/casic/tube/controller/TubeDataController.java index 61486c5..4965449 100644 --- a/src/main/java/com/casic/tube/controller/TubeDataController.java +++ b/src/main/java/com/casic/tube/controller/TubeDataController.java @@ -2,8 +2,8 @@ import com.alibaba.fastjson.JSONObject; import com.casic.common.CasicFrame; -import com.casic.tube.frame.ConfigFrame; -import com.casic.tube.service.ITubeDataService; +import com.casic.common.general.ConfigFrame; +import com.casic.tube.service.ITubeFrameService; import com.casic.util.aep.AepCommandSend; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestBody; @@ -21,7 +21,7 @@ public class TubeDataController { @Resource - private ITubeDataService tubeDataService; + private ITubeFrameService frameService; @RequestMapping("/tube/data/recv") public Object dataRecv(@RequestBody Map map) { @@ -42,10 +42,10 @@ String frameStr = new String(baseBytes); // 根据协议进行解析 - CasicFrame frame = tubeDataService.dataParse(frameStr); + CasicFrame frame = frameService.dataParse(frameStr); // 存库 - tubeDataService.afterAction(frame); + frameService.afterAction(frame); retObj.put("code", 200); retObj.put("success", true); @@ -74,7 +74,7 @@ messageBody.put("datas", map.get("cmdList")); cmdFrame.setMessageBody(messageBody); - String frameStr = tubeDataService.doBuildCommand(cmdFrame); + String frameStr = frameService.doBuildCommand(cmdFrame); // TODO-LIST // 这三个参数根据设备编号从数据库中取 diff --git a/src/main/java/com/casic/tube/frame/ConfigFrame.java b/src/main/java/com/casic/tube/frame/ConfigFrame.java deleted file mode 100644 index 883dad6..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigFrame.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigFrame extends CasicFrame { - - public ConfigFrame() { - setSequence("01"); // 默认序号 - setControl("1"); // 默认为不需要分包 - setMessageType("52"); // 消息大类 52 = SetRequest - } -} diff --git a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java b/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java deleted file mode 100644 index a419145..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigResponseFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "03"; - final String MESSAGE_TYPE_STRING = "SetResponse"; - final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "指令序号" + getSequence() + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/DataFrame.java b/src/main/java/com/casic/tube/frame/DataFrame.java deleted file mode 100644 index 97e07b8..0000000 --- a/src/main/java/com/casic/tube/frame/DataFrame.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import com.casic.dao.model.DataTubeOther; - -import java.util.List; - -public class DataFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "02"; - final String MESSAGE_TYPE_STRING = "Data/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "数据消息/管盯"; - - public List dataItemList; - - public List toDataModelList() { - return null; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append(";"); - builder.append("上报时间:").append(getUptime()).append(";"); - for (DataItem dataItem : dataItemList) { - builder.append("["); - builder.append(dataItem); - builder.append("],"); - } - builder.deleteCharAt(builder.length() - 1); - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/DataItem.java b/src/main/java/com/casic/tube/frame/DataItem.java deleted file mode 100644 index 4e9aceb..0000000 --- a/src/main/java/com/casic/tube/frame/DataItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class DataItem { -} diff --git a/src/main/java/com/casic/tube/frame/EventFrame.java b/src/main/java/com/casic/tube/frame/EventFrame.java deleted file mode 100644 index ea800b4..0000000 --- a/src/main/java/com/casic/tube/frame/EventFrame.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -import java.util.List; - -public class EventFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "01"; - final String MESSAGE_TYPE_STRING = "Event/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "事件消息/管盯"; - - public List eventItemList; - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append("; "); - builder.append("上报时间:").append(getUptime()).append("; "); - for (EventItem eventItem : eventItemList) { - builder.append("["); - builder.append(eventItem); - builder.append("],"); - } - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/EventItem.java b/src/main/java/com/casic/tube/frame/EventItem.java deleted file mode 100644 index a1245bf..0000000 --- a/src/main/java/com/casic/tube/frame/EventItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class EventItem { -} diff --git a/src/main/java/com/casic/tube/frame/HeartFrame.java b/src/main/java/com/casic/tube/frame/HeartFrame.java deleted file mode 100644 index af7e7a6..0000000 --- a/src/main/java/com/casic/tube/frame/HeartFrame.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; - -@Data -public class HeartFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "00"; - final String MESSAGE_TYPE_STRING = "OnlineRequest"; - final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/IMEIFrame.java b/src/main/java/com/casic/tube/frame/IMEIFrame.java deleted file mode 100644 index 9420620..0000000 --- a/src/main/java/com/casic/tube/frame/IMEIFrame.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; - -@Data -public class IMEIFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "05"; - final String MESSAGE_TYPE_STRING = "StartupRequest"; - final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; - - String imei; - String iccid; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "IMEI:" + imei + ";" + - "ICCID:" + iccid + - "}"; - } - - @Override - public void parseMessageBody() { - imei = getMessageBody().getString("IMEI"); - iccid = getMessageBody().getString("ICCID"); - } -} diff --git a/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java b/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java index 50e8a2b..47bf4d6 100644 --- a/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java @@ -3,11 +3,12 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.casic.dao.model.DataTubeOther; -import com.casic.tube.frame.DataFrame; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -19,7 +20,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override @@ -43,8 +45,8 @@ } @Override - public List toDataModelList() { - List dataList = new ArrayList<>(); + public List toDataModelList() { + List dataList = new ArrayList<>(); for (DataItem dataItem : dataItemList) { DataTubeOther data = new DataTubeOther(); diff --git a/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java b/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java index 8d09b10..75e94c7 100644 --- a/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.brs; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java b/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java index 9026b4c..2e5c145 100644 --- a/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java @@ -2,14 +2,11 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.casic.common.CasicFrame; -import com.casic.tube.frame.EventFrame; -import com.casic.tube.frame.EventItem; +import com.casic.common.general.EventFrame; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; -import java.util.List; @Data @Slf4j @@ -17,7 +14,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override diff --git a/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java b/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java index 6c8146c..1792320 100644 --- a/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.brs; -import com.casic.tube.frame.EventItem; +import com.casic.common.general.EventItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java b/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java index e6e541c..b05b358 100644 --- a/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java @@ -3,11 +3,12 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.casic.dao.model.DataTubeOther; -import com.casic.tube.frame.DataFrame; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -19,7 +20,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override @@ -43,8 +45,8 @@ } @Override - public List toDataModelList() { - List dataList = new ArrayList<>(); + public List toDataModelList() { + List dataList = new ArrayList<>(); for (DataItem dataItem : dataItemList) { DataTubeOther data = new DataTubeOther(); diff --git a/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java b/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java index 0aa9bab..e875f2a 100644 --- a/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.mhk; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java b/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java index 9aea120..ec2d005 100644 --- a/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java @@ -2,13 +2,11 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.casic.common.CasicFrame; -import com.casic.tube.frame.EventFrame; +import com.casic.common.general.EventFrame; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; -import java.util.List; @Data @Slf4j @@ -16,7 +14,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override diff --git a/src/main/java/com/casic/tube/frame/mhk/EventItemMHK.java b/src/main/java/com/casic/tube/frame/mhk/EventItemMHK.java index 8f6a536..e5ffed6 100644 --- a/src/main/java/com/casic/tube/frame/mhk/EventItemMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/EventItemMHK.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.mhk; -import com.casic.tube.frame.EventItem; +import com.casic.common.general.EventItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/tp/DataFrameHTTP.java b/src/main/java/com/casic/tube/frame/tp/DataFrameHTTP.java index 23df423..69b7c1f 100644 --- a/src/main/java/com/casic/tube/frame/tp/DataFrameHTTP.java +++ b/src/main/java/com/casic/tube/frame/tp/DataFrameHTTP.java @@ -3,11 +3,12 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.casic.dao.model.DataTubeOther; -import com.casic.tube.frame.DataFrame; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -18,6 +19,12 @@ public class DataFrameHTTP extends DataFrame { @Override + public String toString(){ + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); + } + + @Override public void parseMessageBody() { JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); dataItemList = new ArrayList<>(); @@ -40,8 +47,8 @@ } @Override - public List toDataModelList() { - List dataList = new ArrayList<>(); + public List toDataModelList() { + List dataList = new ArrayList<>(); for (DataItem dataItem : dataItemList) { DataTubeOther data = new DataTubeOther(); diff --git a/src/main/java/com/casic/tube/frame/tp/DataItemHTTP.java b/src/main/java/com/casic/tube/frame/tp/DataItemHTTP.java index e5281eb..49d7c87 100644 --- a/src/main/java/com/casic/tube/frame/tp/DataItemHTTP.java +++ b/src/main/java/com/casic/tube/frame/tp/DataItemHTTP.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.tp; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/tube/protocol/CasicTubeProtocolImpl.java deleted file mode 100644 index 4fdd78c..0000000 --- a/src/main/java/com/casic/tube/protocol/CasicTubeProtocolImpl.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.casic.tube.protocol; - -import com.alibaba.fastjson.JSONObject; -import com.casic.common.CasicFrame; -import com.casic.common.CasicProtocol; -import org.springframework.stereotype.Component; - -@Component -public class CasicTubeProtocolImpl implements CasicProtocol { - @Override - public boolean checkFrame(String frame) { - boolean valid = checkFrameHeaderAndTail(frame); - if (valid) { - valid = checkFrameLength(frame); - } - - return valid; - } - - private boolean checkFrameHeaderAndTail(String frame) { - return (frame.substring(0, 2).equalsIgnoreCase("AA")) && - (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); - } - - private boolean checkFrameLength(String frame) { - String lengthStr = frame.substring(4, 7); - int length = Integer.parseInt(lengthStr); - - return frame.length() == length + 9; - } - - @Override - public String getDeviceType(String frame) { - return frame.substring(7, 9); - } - - @Override - public String getDeviceId(String frame) { - return frame.substring(9, 21); - } - - @Override - public String getManufacturerCode(String frame) { - return frame.substring(11, 13); - } - - @Override - public String getMessageType(String frame) { - return frame.substring(21, 23); - } - - @Override - public String getMessageBody(String frame) { - return frame.substring(26, frame.length() - 16); - } - - @Override - public JSONObject parseMessageBody(String messageBody) { - return JSONObject.parseObject(messageBody); - } - - @Override - public String getUptime(String frame) { - return frame.substring(frame.length() - 16, frame.length() - 2); - } - - @Override - public String buildFrameStr(CasicFrame frame) { - StringBuilder builder = new StringBuilder(); - - builder.append(frame.getDeviceType()); - builder.append(frame.getDeviceCode()); - builder.append(frame.getMessageType()); - builder.append(frame.getSequence()); - builder.append(frame.getControl()); - builder.append(frame.getMessageBody().toJSONString()); - builder.append(frame.getUptime()); - - builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 - builder.insert(0, frame.getVersion()); - builder.insert(0, frame.getHEADER()); - builder.append(frame.getTAIL()); - - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/service/ITubeDataService.java b/src/main/java/com/casic/tube/service/ITubeDataService.java deleted file mode 100644 index c9dafea..0000000 --- a/src/main/java/com/casic/tube/service/ITubeDataService.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.casic.tube.service; - -import com.alibaba.fastjson.JSONObject; -import com.casic.common.CasicFrame; - -public interface ITubeDataService { - - CasicFrame dataParse(String frame); - - String doBuildCommand(CasicFrame cmd); - - void afterAction(CasicFrame frame); -} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java new file mode 100644 index 0000000..95d2bd4 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java @@ -0,0 +1,8 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.DataMonitorPipeOther; + +public interface IDataSentinelOtherService extends IService { + +} diff --git a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java index d6b1200..0290829 100644 --- a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java +++ b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java @@ -1,7 +1,6 @@ package com.casic.dao.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.dao.model.DataTubeOther; import com.casic.dao.model.DeviceWellView; public interface IDeviceWellViewService extends IService { diff --git a/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java new file mode 100644 index 0000000..be34f77 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java @@ -0,0 +1,16 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.BusDeviceMapper; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import org.springframework.stereotype.Service; + +@Service +public class BusDeviceServiceImpl extends ServiceImpl implements IBusDeviceService { + + @Override + public BusDevice getDeviceByCode(String devCode) { + return baseMapper.getOneByDevCode(devCode); + } +} diff --git a/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java new file mode 100644 index 0000000..0db2007 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java @@ -0,0 +1,11 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.DataSentinelOtherMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.service.IDataSentinelOtherService; +import org.springframework.stereotype.Service; + +@Service +public class DataSentinelOtherServiceImpl extends ServiceImpl implements IDataSentinelOtherService { +} diff --git a/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java new file mode 100644 index 0000000..d8c5ef2 --- /dev/null +++ b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java @@ -0,0 +1,111 @@ +package com.casic.protocol; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.CasicProtocol; +import org.springframework.stereotype.Component; + +@Component +public class CasicTubeProtocolImpl implements CasicProtocol { + @Override + public boolean checkFrame(String frame) { + boolean valid = checkFrameHeaderAndTail(frame); + if (valid) { + valid = checkFrameLength(frame); + } + + return valid; + } + + private boolean checkFrameHeaderAndTail(String frame) { + return (frame.substring(0, 2).equalsIgnoreCase("AA")) && + (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); + } + + private boolean checkFrameLength(String frame) { + String lengthStr = frame.substring(4, 7); + int length = Integer.parseInt(lengthStr); + + return frame.length() == length + 9; + } + + @Override + public String getDeviceType(String frame) { + return frame.substring(7, 9); + } + + @Override + public String getDeviceId(String frame) { + return frame.substring(9, 21); + } + + @Override + public String getManufacturerCode(String frame) { + return frame.substring(11, 13); + } + + @Override + public String getMessageType(String frame) { + return frame.substring(21, 23); + } + + @Override + public String getMessageSequence(String frame) { + return frame.substring(23, 25); + } + + @Override + public String getMessageBody(String frame) { + return frame.substring(26, frame.length() - 16); + } + + @Override + public JSONObject parseMessageBody(String messageBody) { + return JSONObject.parseObject(messageBody); + } + + @Override + public String getUptime(String frame) { + return frame.substring(frame.length() - 16, frame.length() - 2); + } + + @Override + public String buildFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append(frame.getMessageBody().toJSONString()); + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } + + @Override + public String buildReplyFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append("00"); // 消息响应类消息 消息体为00 + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/senitnel/controller/SentinelDataController.java b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java new file mode 100644 index 0000000..633c072 --- /dev/null +++ b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java @@ -0,0 +1,120 @@ +package com.casic.senitnel.controller; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.general.ConfigFrame; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import com.casic.senitnel.service.ISentinelFrameService; +import com.casic.util.aep.AepCommandSend; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Base64; +import java.util.Map; + +@Slf4j +@RestController +public class SentinelDataController { + + @Resource + private ISentinelFrameService frameService; + + @Resource + private IBusDeviceService deviceService; + + @RequestMapping("/sentinel/data/recv") + public Object dataRecv(@RequestBody Map map) { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + + JSONObject recvObj = (JSONObject) JSONObject.toJSON(map); + if (recvObj.containsKey("payload")) { + JSONObject payload = recvObj.getJSONObject("payload"); + String value = payload.getString("APPdata"); + + if (value.isEmpty()) { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } else { + byte[] baseBytes = Base64.getDecoder().decode(value); + String frameStr = new String(baseBytes); + + // 根据协议进行解析 + CasicFrame frame = frameService.dataParse(frameStr); + + if (frame != null) { + // 回复响应 + String replyFrameStr = frameService.replyMessage(frame.getDeviceCode(), frame.getSequence()); + + // 从数据库中获取master-api-key 回复响应消息 + BusDevice device = deviceService.getDeviceByCode(frame.getDeviceCode()); + if (device != null && StringUtils.isNotBlank(device.getMasterApiKey())) { + String masterApiKey = device.getMasterApiKey(); + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + + try { + int code = aepCommandSend.handleAndReply(replyFrameStr); + } catch (Exception ex) { + log.error("向设备回复响应异常:{}", ex.getMessage()); + } + } + + // 存库 + frameService.afterAction(frame); + } + + retObj.put("code", 200); + retObj.put("success", true); + } + } else { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } + + return retObj; + } + + @RequestMapping("/sentinel/config/send") + public Object configSend(@RequestBody Map map) throws Exception { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + CasicFrame cmdFrame = new ConfigFrame(); + cmdFrame.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + cmdFrame.setDeviceCode((String) map.get("devCode")); + cmdFrame.setSequence("01"); + cmdFrame.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + JSONObject messageBody = new JSONObject(); + messageBody.put("datas", map.get("cmdList")); + cmdFrame.setMessageBody(messageBody); + + String frameStr = frameService.doBuildCommand(cmdFrame); + + // TODO-LIST + // 这三个参数根据设备编号从数据库中取 + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + String masterApiKey = (String) map.get("masterApiKey"); + + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + int code = aepCommandSend.handleAndReply(frameStr); + + retObj.put("code", 200); + retObj.put("success", true); + retObj.put("AEPRetCode", code); + return retObj; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java new file mode 100644 index 0000000..368af03 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java @@ -0,0 +1,82 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; +import com.casic.dao.model.DataMonitorPipeOther; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class DataFrameNCX extends DataFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + dataItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + DataItemNCX dataItem = new DataItemNCX(); + + dataItem.setLenL(dataObj.getString("LENGL")); + dataItem.setLenR(dataObj.getString("LENGR")); + dataItem.setBat(dataObj.getString("BAT")); + dataItem.setCh4L(dataObj.getString("CH4L")); + dataItem.setCh4R(dataObj.getString("CH4R")); + dataItem.setSlope(dataObj.getString("SLOPING")); + dataItem.setDestroy(dataObj.getString("DESTROY")); + dataItem.setLeak(dataObj.getString("LEAK")); + dataItem.setDiscL(dataObj.getString("DISCL")); + dataItem.setDiscR(dataObj.getString("DISCR")); + dataItem.setVibL(dataObj.getString("VIBL")); + dataItem.setVibR(dataObj.getString("VIBR")); + dataItem.setTime(dataObj.getString("UPTIME")); + + dataItemList.add(dataItem); + } + } + + @Override + public List toDataModelList() { + List dataList = new ArrayList<>(); + for (DataItem dataItem : dataItemList) { + DataMonitorPipeOther data = new DataMonitorPipeOther(); + + data.setDevcode(getDeviceCode()); + data.setLeftLength(((DataItemNCX)dataItem).getLenL()); + data.setRightLength(((DataItemNCX)dataItem).getLenR()); + data.setLeftGas(((DataItemNCX)dataItem).getCh4L()); + data.setRightGas(((DataItemNCX)dataItem).getCh4R()); + data.setVbat(((DataItemNCX)dataItem).getBat()); + data.setPipeInclineAlarm(((DataItemNCX)dataItem).getSlope()); + data.setPipeBreakAlarm(((DataItemNCX)dataItem).getDestroy()); + data.setGasAlarm(((DataItemNCX)dataItem).getLeak()); + data.setLeftOfflineAlarm(((DataItemNCX)dataItem).getDiscL()); + data.setRightOfflineAlarm(((DataItemNCX)dataItem).getDiscR()); + data.setLeftVibrateAlarm(((DataItemNCX)dataItem).getVibL()); + data.setRightVibrateAlarm(((DataItemNCX)dataItem).getVibR()); + data.setUptime(LocalDateTime.parse(((DataItemNCX)dataItem).getTime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 采集时间 + data.setLogtime(LocalDateTime.parse(getUptime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 上报时间 + + dataList.add(data); + } + + return dataList; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java new file mode 100644 index 0000000..372ac73 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java @@ -0,0 +1,31 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.DataItem; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class DataItemNCX extends DataItem { + String lenL; // 左侧指示带长度 + String lenR; // 右侧指示带长度 + String ch4L; // 左侧甲烷浓度值 + String ch4R; // 右侧甲烷浓度值 + String bat; // 电池电压 + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String spare; // 备用 + String time; // 采集时间 + + @Override + public String toString() { + return "气体浓度值:" + "(" + ch4L + "," + ch4R + ")" + "%LEL;" + + "电池电压值:" + bat + "v;" + + "采样时间:" + time; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java new file mode 100644 index 0000000..b3bbcf4 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java @@ -0,0 +1,43 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.EventFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class EventFrameNCX extends EventFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + eventItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + EventItemNCX eventItem = new EventItemNCX(); + + eventItem.setSlope(dataObj.getString("SLOPING")); + eventItem.setDestroy(dataObj.getString("DESTROY")); + eventItem.setLeak(dataObj.getString("LEAK")); + eventItem.setDiscL(dataObj.getString("DISCL")); + eventItem.setDiscR(dataObj.getString("DISCR")); + eventItem.setVibL(dataObj.getString("VIBL")); + eventItem.setVibR(dataObj.getString("VIBR")); + eventItem.setTime(dataObj.getString("UPTIME")); + + eventItemList.add(eventItem); + } + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java new file mode 100644 index 0000000..1a560d0 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java @@ -0,0 +1,49 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.EventItem; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.commons.lang3.StringUtils; + +@EqualsAndHashCode(callSuper = true) +@Data +public class EventItemNCX extends EventItem { + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String time; // 采集时间 + + @Override + public String toString() { + String str = ""; + if (StringUtils.isNotBlank(slope) && slope.equalsIgnoreCase("1")) { + str += "[倾斜报警]"; + } + if (StringUtils.isNotBlank(destroy) && destroy.equalsIgnoreCase("1")) { + str += "[破坏报警]"; + } + if (StringUtils.isNotBlank(leak) && leak.equalsIgnoreCase("1")) { + str += "[甲烷泄漏报警]"; + } + if (StringUtils.isNotBlank(discL) && discL.equalsIgnoreCase("1")) { + str += "[左侧断线报警]"; + } + if (StringUtils.isNotBlank(discR) && discR.equalsIgnoreCase("1")) { + str += "[右侧断线报警]"; + } + if (StringUtils.isNotBlank(vibL) && vibL.equalsIgnoreCase("1")) { + str += "[左侧振动报警]"; + } + if (StringUtils.isNotBlank(vibR) && vibR.equalsIgnoreCase("1")) { + str += "[右侧振动报警]"; + } + str += "采样时间:" + time; + + return str; + + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java new file mode 100644 index 0000000..343c4d6 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java @@ -0,0 +1,37 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class InfoFrameNCX extends CasicFrame { + + String workMode; + String model; + String hwVersion; + String softVersion; + String sensorType; + + @Override + public String toString() { + return "设备编号: " + getDeviceCode() + "; " + + "设备工作模式: " + workMode + " ; " + + "设备型号: " + model + " ; " + + "版本号: " + hwVersion + ", " + softVersion + "; " + + "传感器类型: " + sensorType + " ; " + + "上报时间: " + getUptime(); + } + + @Override + public void parseMessageBody() { + workMode = getMessageBody().getString("WORKMODE"); + model = getMessageBody().getString("MODEL"); + hwVersion = getMessageBody().getString("HWVERSION"); + softVersion = getMessageBody().getString("SOFTVERSION"); + sensorType = getMessageBody().getString("SENSORTYPE"); + } +} diff --git a/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java new file mode 100644 index 0000000..e76fc86 --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java @@ -0,0 +1,14 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; + +public interface ISentinelFrameService { + + CasicFrame dataParse(String frame); + + String replyMessage(String deviceCode, String sequence); + + String doBuildCommand(CasicFrame cmd); + + void afterAction(CasicFrame frame); +} diff --git a/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java new file mode 100644 index 0000000..803ff0e --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java @@ -0,0 +1,109 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; +import com.casic.common.CasicFrameBuildFactory; +import com.casic.common.CasicProtocol; +import com.casic.common.general.DataFrame; +import com.casic.common.general.EventFrame; +import com.casic.common.general.ReplyFrame; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.model.DeviceWellView; +import com.casic.dao.service.IDataSentinelOtherService; +import com.casic.dao.service.IDeviceWellViewService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + + +@Service +@Slf4j +public class SentinelFrameServiceImpl implements ISentinelFrameService { + + @Resource + private CasicProtocol protocol; + + @Resource + IDataSentinelOtherService sentinelDataService; + + @Resource + IDeviceWellViewService deviceService; + + public CasicFrame dataParse(String frame) { + // 1. 判断帧结构 + boolean frameValid = protocol.checkFrame(frame); + if (frameValid) { + // 2. 获取帧结构中的关键字段信息 + String deviceId = protocol.getDeviceId(frame); + String deviceType = protocol.getDeviceType(frame); + String messageType = protocol.getMessageType(frame); + String messageBody = protocol.getMessageBody(frame).toUpperCase(); + String uptime = protocol.getUptime(frame); + String sequence = protocol.getMessageSequence(frame); + + String manufacturerCode = protocol.getManufacturerCode(frame); + CasicFrame sentinelFrame = CasicFrameBuildFactory.buildCasicFrame(messageType, manufacturerCode, deviceType); + + if (sentinelFrame != null) { + sentinelFrame.setDeviceCode(deviceId); + sentinelFrame.setUptime(uptime); + sentinelFrame.setMessageType(messageType); + sentinelFrame.setSequence(sequence); + + // 心跳类的消息不解析MessageBody + if (!sentinelFrame.getMessageType().equals("00")) { + sentinelFrame.setMessageBody(protocol.parseMessageBody(messageBody)); + sentinelFrame.parseMessageBody(); + } + + log.info("收到设备消息:{}", sentinelFrame); + return sentinelFrame; + } + } else { + log.error("消息帧解析异常"); + } + + return null; + } + + @Override + public String replyMessage(String deviceCode, String sequence) { + CasicFrame reply = new ReplyFrame(); + reply.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + reply.setDeviceCode(deviceCode); + reply.setSequence(sequence); + reply.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + return protocol.buildReplyFrameStr(reply); + } + + @Override + public String doBuildCommand(CasicFrame cmd) { + return protocol.buildFrameStr(cmd); + } + + @Override + public void afterAction(CasicFrame frame) { + // 数据消息帧 进行存库操作 + if (frame instanceof DataFrame) { + String devCode = frame.getDeviceCode(); + DeviceWellView devWellView = deviceService.getDeviceWellViewByDevCode(devCode); + String wellCode = ""; + if (devWellView != null) { + wellCode = devWellView.getWellCode(); + } + List dataList = ((DataFrame) frame).toDataModelList(); + if (dataList != null) { + for (Serializable item : dataList) { + DataMonitorPipeOther data = (DataMonitorPipeOther) item; + data.setWellCode(wellCode); + sentinelDataService.save(data); + } + } + } + } +} diff --git a/src/main/java/com/casic/tube/controller/TubeDataController.java b/src/main/java/com/casic/tube/controller/TubeDataController.java index 61486c5..4965449 100644 --- a/src/main/java/com/casic/tube/controller/TubeDataController.java +++ b/src/main/java/com/casic/tube/controller/TubeDataController.java @@ -2,8 +2,8 @@ import com.alibaba.fastjson.JSONObject; import com.casic.common.CasicFrame; -import com.casic.tube.frame.ConfigFrame; -import com.casic.tube.service.ITubeDataService; +import com.casic.common.general.ConfigFrame; +import com.casic.tube.service.ITubeFrameService; import com.casic.util.aep.AepCommandSend; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestBody; @@ -21,7 +21,7 @@ public class TubeDataController { @Resource - private ITubeDataService tubeDataService; + private ITubeFrameService frameService; @RequestMapping("/tube/data/recv") public Object dataRecv(@RequestBody Map map) { @@ -42,10 +42,10 @@ String frameStr = new String(baseBytes); // 根据协议进行解析 - CasicFrame frame = tubeDataService.dataParse(frameStr); + CasicFrame frame = frameService.dataParse(frameStr); // 存库 - tubeDataService.afterAction(frame); + frameService.afterAction(frame); retObj.put("code", 200); retObj.put("success", true); @@ -74,7 +74,7 @@ messageBody.put("datas", map.get("cmdList")); cmdFrame.setMessageBody(messageBody); - String frameStr = tubeDataService.doBuildCommand(cmdFrame); + String frameStr = frameService.doBuildCommand(cmdFrame); // TODO-LIST // 这三个参数根据设备编号从数据库中取 diff --git a/src/main/java/com/casic/tube/frame/ConfigFrame.java b/src/main/java/com/casic/tube/frame/ConfigFrame.java deleted file mode 100644 index 883dad6..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigFrame.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigFrame extends CasicFrame { - - public ConfigFrame() { - setSequence("01"); // 默认序号 - setControl("1"); // 默认为不需要分包 - setMessageType("52"); // 消息大类 52 = SetRequest - } -} diff --git a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java b/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java deleted file mode 100644 index a419145..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigResponseFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "03"; - final String MESSAGE_TYPE_STRING = "SetResponse"; - final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "指令序号" + getSequence() + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/DataFrame.java b/src/main/java/com/casic/tube/frame/DataFrame.java deleted file mode 100644 index 97e07b8..0000000 --- a/src/main/java/com/casic/tube/frame/DataFrame.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import com.casic.dao.model.DataTubeOther; - -import java.util.List; - -public class DataFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "02"; - final String MESSAGE_TYPE_STRING = "Data/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "数据消息/管盯"; - - public List dataItemList; - - public List toDataModelList() { - return null; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append(";"); - builder.append("上报时间:").append(getUptime()).append(";"); - for (DataItem dataItem : dataItemList) { - builder.append("["); - builder.append(dataItem); - builder.append("],"); - } - builder.deleteCharAt(builder.length() - 1); - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/DataItem.java b/src/main/java/com/casic/tube/frame/DataItem.java deleted file mode 100644 index 4e9aceb..0000000 --- a/src/main/java/com/casic/tube/frame/DataItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class DataItem { -} diff --git a/src/main/java/com/casic/tube/frame/EventFrame.java b/src/main/java/com/casic/tube/frame/EventFrame.java deleted file mode 100644 index ea800b4..0000000 --- a/src/main/java/com/casic/tube/frame/EventFrame.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -import java.util.List; - -public class EventFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "01"; - final String MESSAGE_TYPE_STRING = "Event/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "事件消息/管盯"; - - public List eventItemList; - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append("; "); - builder.append("上报时间:").append(getUptime()).append("; "); - for (EventItem eventItem : eventItemList) { - builder.append("["); - builder.append(eventItem); - builder.append("],"); - } - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/EventItem.java b/src/main/java/com/casic/tube/frame/EventItem.java deleted file mode 100644 index a1245bf..0000000 --- a/src/main/java/com/casic/tube/frame/EventItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class EventItem { -} diff --git a/src/main/java/com/casic/tube/frame/HeartFrame.java b/src/main/java/com/casic/tube/frame/HeartFrame.java deleted file mode 100644 index af7e7a6..0000000 --- a/src/main/java/com/casic/tube/frame/HeartFrame.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; - -@Data -public class HeartFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "00"; - final String MESSAGE_TYPE_STRING = "OnlineRequest"; - final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/IMEIFrame.java b/src/main/java/com/casic/tube/frame/IMEIFrame.java deleted file mode 100644 index 9420620..0000000 --- a/src/main/java/com/casic/tube/frame/IMEIFrame.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; - -@Data -public class IMEIFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "05"; - final String MESSAGE_TYPE_STRING = "StartupRequest"; - final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; - - String imei; - String iccid; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "IMEI:" + imei + ";" + - "ICCID:" + iccid + - "}"; - } - - @Override - public void parseMessageBody() { - imei = getMessageBody().getString("IMEI"); - iccid = getMessageBody().getString("ICCID"); - } -} diff --git a/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java b/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java index 50e8a2b..47bf4d6 100644 --- a/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java @@ -3,11 +3,12 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.casic.dao.model.DataTubeOther; -import com.casic.tube.frame.DataFrame; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -19,7 +20,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override @@ -43,8 +45,8 @@ } @Override - public List toDataModelList() { - List dataList = new ArrayList<>(); + public List toDataModelList() { + List dataList = new ArrayList<>(); for (DataItem dataItem : dataItemList) { DataTubeOther data = new DataTubeOther(); diff --git a/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java b/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java index 8d09b10..75e94c7 100644 --- a/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.brs; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java b/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java index 9026b4c..2e5c145 100644 --- a/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java @@ -2,14 +2,11 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.casic.common.CasicFrame; -import com.casic.tube.frame.EventFrame; -import com.casic.tube.frame.EventItem; +import com.casic.common.general.EventFrame; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; -import java.util.List; @Data @Slf4j @@ -17,7 +14,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override diff --git a/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java b/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java index 6c8146c..1792320 100644 --- a/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.brs; -import com.casic.tube.frame.EventItem; +import com.casic.common.general.EventItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java b/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java index e6e541c..b05b358 100644 --- a/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java @@ -3,11 +3,12 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.casic.dao.model.DataTubeOther; -import com.casic.tube.frame.DataFrame; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -19,7 +20,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override @@ -43,8 +45,8 @@ } @Override - public List toDataModelList() { - List dataList = new ArrayList<>(); + public List toDataModelList() { + List dataList = new ArrayList<>(); for (DataItem dataItem : dataItemList) { DataTubeOther data = new DataTubeOther(); diff --git a/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java b/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java index 0aa9bab..e875f2a 100644 --- a/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.mhk; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java b/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java index 9aea120..ec2d005 100644 --- a/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java @@ -2,13 +2,11 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.casic.common.CasicFrame; -import com.casic.tube.frame.EventFrame; +import com.casic.common.general.EventFrame; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; -import java.util.List; @Data @Slf4j @@ -16,7 +14,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override diff --git a/src/main/java/com/casic/tube/frame/mhk/EventItemMHK.java b/src/main/java/com/casic/tube/frame/mhk/EventItemMHK.java index 8f6a536..e5ffed6 100644 --- a/src/main/java/com/casic/tube/frame/mhk/EventItemMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/EventItemMHK.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.mhk; -import com.casic.tube.frame.EventItem; +import com.casic.common.general.EventItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/tp/DataFrameHTTP.java b/src/main/java/com/casic/tube/frame/tp/DataFrameHTTP.java index 23df423..69b7c1f 100644 --- a/src/main/java/com/casic/tube/frame/tp/DataFrameHTTP.java +++ b/src/main/java/com/casic/tube/frame/tp/DataFrameHTTP.java @@ -3,11 +3,12 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.casic.dao.model.DataTubeOther; -import com.casic.tube.frame.DataFrame; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -18,6 +19,12 @@ public class DataFrameHTTP extends DataFrame { @Override + public String toString(){ + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); + } + + @Override public void parseMessageBody() { JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); dataItemList = new ArrayList<>(); @@ -40,8 +47,8 @@ } @Override - public List toDataModelList() { - List dataList = new ArrayList<>(); + public List toDataModelList() { + List dataList = new ArrayList<>(); for (DataItem dataItem : dataItemList) { DataTubeOther data = new DataTubeOther(); diff --git a/src/main/java/com/casic/tube/frame/tp/DataItemHTTP.java b/src/main/java/com/casic/tube/frame/tp/DataItemHTTP.java index e5281eb..49d7c87 100644 --- a/src/main/java/com/casic/tube/frame/tp/DataItemHTTP.java +++ b/src/main/java/com/casic/tube/frame/tp/DataItemHTTP.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.tp; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/tube/protocol/CasicTubeProtocolImpl.java deleted file mode 100644 index 4fdd78c..0000000 --- a/src/main/java/com/casic/tube/protocol/CasicTubeProtocolImpl.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.casic.tube.protocol; - -import com.alibaba.fastjson.JSONObject; -import com.casic.common.CasicFrame; -import com.casic.common.CasicProtocol; -import org.springframework.stereotype.Component; - -@Component -public class CasicTubeProtocolImpl implements CasicProtocol { - @Override - public boolean checkFrame(String frame) { - boolean valid = checkFrameHeaderAndTail(frame); - if (valid) { - valid = checkFrameLength(frame); - } - - return valid; - } - - private boolean checkFrameHeaderAndTail(String frame) { - return (frame.substring(0, 2).equalsIgnoreCase("AA")) && - (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); - } - - private boolean checkFrameLength(String frame) { - String lengthStr = frame.substring(4, 7); - int length = Integer.parseInt(lengthStr); - - return frame.length() == length + 9; - } - - @Override - public String getDeviceType(String frame) { - return frame.substring(7, 9); - } - - @Override - public String getDeviceId(String frame) { - return frame.substring(9, 21); - } - - @Override - public String getManufacturerCode(String frame) { - return frame.substring(11, 13); - } - - @Override - public String getMessageType(String frame) { - return frame.substring(21, 23); - } - - @Override - public String getMessageBody(String frame) { - return frame.substring(26, frame.length() - 16); - } - - @Override - public JSONObject parseMessageBody(String messageBody) { - return JSONObject.parseObject(messageBody); - } - - @Override - public String getUptime(String frame) { - return frame.substring(frame.length() - 16, frame.length() - 2); - } - - @Override - public String buildFrameStr(CasicFrame frame) { - StringBuilder builder = new StringBuilder(); - - builder.append(frame.getDeviceType()); - builder.append(frame.getDeviceCode()); - builder.append(frame.getMessageType()); - builder.append(frame.getSequence()); - builder.append(frame.getControl()); - builder.append(frame.getMessageBody().toJSONString()); - builder.append(frame.getUptime()); - - builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 - builder.insert(0, frame.getVersion()); - builder.insert(0, frame.getHEADER()); - builder.append(frame.getTAIL()); - - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/service/ITubeDataService.java b/src/main/java/com/casic/tube/service/ITubeDataService.java deleted file mode 100644 index c9dafea..0000000 --- a/src/main/java/com/casic/tube/service/ITubeDataService.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.casic.tube.service; - -import com.alibaba.fastjson.JSONObject; -import com.casic.common.CasicFrame; - -public interface ITubeDataService { - - CasicFrame dataParse(String frame); - - String doBuildCommand(CasicFrame cmd); - - void afterAction(CasicFrame frame); -} diff --git a/src/main/java/com/casic/tube/service/ITubeFrameService.java b/src/main/java/com/casic/tube/service/ITubeFrameService.java new file mode 100644 index 0000000..1ba209c --- /dev/null +++ b/src/main/java/com/casic/tube/service/ITubeFrameService.java @@ -0,0 +1,12 @@ +package com.casic.tube.service; + +import com.casic.common.CasicFrame; + +public interface ITubeFrameService { + + CasicFrame dataParse(String frame); + + String doBuildCommand(CasicFrame cmd); + + void afterAction(CasicFrame frame); +} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java new file mode 100644 index 0000000..95d2bd4 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java @@ -0,0 +1,8 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.DataMonitorPipeOther; + +public interface IDataSentinelOtherService extends IService { + +} diff --git a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java index d6b1200..0290829 100644 --- a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java +++ b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java @@ -1,7 +1,6 @@ package com.casic.dao.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.dao.model.DataTubeOther; import com.casic.dao.model.DeviceWellView; public interface IDeviceWellViewService extends IService { diff --git a/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java new file mode 100644 index 0000000..be34f77 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java @@ -0,0 +1,16 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.BusDeviceMapper; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import org.springframework.stereotype.Service; + +@Service +public class BusDeviceServiceImpl extends ServiceImpl implements IBusDeviceService { + + @Override + public BusDevice getDeviceByCode(String devCode) { + return baseMapper.getOneByDevCode(devCode); + } +} diff --git a/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java new file mode 100644 index 0000000..0db2007 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java @@ -0,0 +1,11 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.DataSentinelOtherMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.service.IDataSentinelOtherService; +import org.springframework.stereotype.Service; + +@Service +public class DataSentinelOtherServiceImpl extends ServiceImpl implements IDataSentinelOtherService { +} diff --git a/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java new file mode 100644 index 0000000..d8c5ef2 --- /dev/null +++ b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java @@ -0,0 +1,111 @@ +package com.casic.protocol; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.CasicProtocol; +import org.springframework.stereotype.Component; + +@Component +public class CasicTubeProtocolImpl implements CasicProtocol { + @Override + public boolean checkFrame(String frame) { + boolean valid = checkFrameHeaderAndTail(frame); + if (valid) { + valid = checkFrameLength(frame); + } + + return valid; + } + + private boolean checkFrameHeaderAndTail(String frame) { + return (frame.substring(0, 2).equalsIgnoreCase("AA")) && + (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); + } + + private boolean checkFrameLength(String frame) { + String lengthStr = frame.substring(4, 7); + int length = Integer.parseInt(lengthStr); + + return frame.length() == length + 9; + } + + @Override + public String getDeviceType(String frame) { + return frame.substring(7, 9); + } + + @Override + public String getDeviceId(String frame) { + return frame.substring(9, 21); + } + + @Override + public String getManufacturerCode(String frame) { + return frame.substring(11, 13); + } + + @Override + public String getMessageType(String frame) { + return frame.substring(21, 23); + } + + @Override + public String getMessageSequence(String frame) { + return frame.substring(23, 25); + } + + @Override + public String getMessageBody(String frame) { + return frame.substring(26, frame.length() - 16); + } + + @Override + public JSONObject parseMessageBody(String messageBody) { + return JSONObject.parseObject(messageBody); + } + + @Override + public String getUptime(String frame) { + return frame.substring(frame.length() - 16, frame.length() - 2); + } + + @Override + public String buildFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append(frame.getMessageBody().toJSONString()); + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } + + @Override + public String buildReplyFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append("00"); // 消息响应类消息 消息体为00 + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/senitnel/controller/SentinelDataController.java b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java new file mode 100644 index 0000000..633c072 --- /dev/null +++ b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java @@ -0,0 +1,120 @@ +package com.casic.senitnel.controller; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.general.ConfigFrame; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import com.casic.senitnel.service.ISentinelFrameService; +import com.casic.util.aep.AepCommandSend; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Base64; +import java.util.Map; + +@Slf4j +@RestController +public class SentinelDataController { + + @Resource + private ISentinelFrameService frameService; + + @Resource + private IBusDeviceService deviceService; + + @RequestMapping("/sentinel/data/recv") + public Object dataRecv(@RequestBody Map map) { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + + JSONObject recvObj = (JSONObject) JSONObject.toJSON(map); + if (recvObj.containsKey("payload")) { + JSONObject payload = recvObj.getJSONObject("payload"); + String value = payload.getString("APPdata"); + + if (value.isEmpty()) { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } else { + byte[] baseBytes = Base64.getDecoder().decode(value); + String frameStr = new String(baseBytes); + + // 根据协议进行解析 + CasicFrame frame = frameService.dataParse(frameStr); + + if (frame != null) { + // 回复响应 + String replyFrameStr = frameService.replyMessage(frame.getDeviceCode(), frame.getSequence()); + + // 从数据库中获取master-api-key 回复响应消息 + BusDevice device = deviceService.getDeviceByCode(frame.getDeviceCode()); + if (device != null && StringUtils.isNotBlank(device.getMasterApiKey())) { + String masterApiKey = device.getMasterApiKey(); + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + + try { + int code = aepCommandSend.handleAndReply(replyFrameStr); + } catch (Exception ex) { + log.error("向设备回复响应异常:{}", ex.getMessage()); + } + } + + // 存库 + frameService.afterAction(frame); + } + + retObj.put("code", 200); + retObj.put("success", true); + } + } else { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } + + return retObj; + } + + @RequestMapping("/sentinel/config/send") + public Object configSend(@RequestBody Map map) throws Exception { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + CasicFrame cmdFrame = new ConfigFrame(); + cmdFrame.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + cmdFrame.setDeviceCode((String) map.get("devCode")); + cmdFrame.setSequence("01"); + cmdFrame.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + JSONObject messageBody = new JSONObject(); + messageBody.put("datas", map.get("cmdList")); + cmdFrame.setMessageBody(messageBody); + + String frameStr = frameService.doBuildCommand(cmdFrame); + + // TODO-LIST + // 这三个参数根据设备编号从数据库中取 + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + String masterApiKey = (String) map.get("masterApiKey"); + + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + int code = aepCommandSend.handleAndReply(frameStr); + + retObj.put("code", 200); + retObj.put("success", true); + retObj.put("AEPRetCode", code); + return retObj; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java new file mode 100644 index 0000000..368af03 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java @@ -0,0 +1,82 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; +import com.casic.dao.model.DataMonitorPipeOther; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class DataFrameNCX extends DataFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + dataItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + DataItemNCX dataItem = new DataItemNCX(); + + dataItem.setLenL(dataObj.getString("LENGL")); + dataItem.setLenR(dataObj.getString("LENGR")); + dataItem.setBat(dataObj.getString("BAT")); + dataItem.setCh4L(dataObj.getString("CH4L")); + dataItem.setCh4R(dataObj.getString("CH4R")); + dataItem.setSlope(dataObj.getString("SLOPING")); + dataItem.setDestroy(dataObj.getString("DESTROY")); + dataItem.setLeak(dataObj.getString("LEAK")); + dataItem.setDiscL(dataObj.getString("DISCL")); + dataItem.setDiscR(dataObj.getString("DISCR")); + dataItem.setVibL(dataObj.getString("VIBL")); + dataItem.setVibR(dataObj.getString("VIBR")); + dataItem.setTime(dataObj.getString("UPTIME")); + + dataItemList.add(dataItem); + } + } + + @Override + public List toDataModelList() { + List dataList = new ArrayList<>(); + for (DataItem dataItem : dataItemList) { + DataMonitorPipeOther data = new DataMonitorPipeOther(); + + data.setDevcode(getDeviceCode()); + data.setLeftLength(((DataItemNCX)dataItem).getLenL()); + data.setRightLength(((DataItemNCX)dataItem).getLenR()); + data.setLeftGas(((DataItemNCX)dataItem).getCh4L()); + data.setRightGas(((DataItemNCX)dataItem).getCh4R()); + data.setVbat(((DataItemNCX)dataItem).getBat()); + data.setPipeInclineAlarm(((DataItemNCX)dataItem).getSlope()); + data.setPipeBreakAlarm(((DataItemNCX)dataItem).getDestroy()); + data.setGasAlarm(((DataItemNCX)dataItem).getLeak()); + data.setLeftOfflineAlarm(((DataItemNCX)dataItem).getDiscL()); + data.setRightOfflineAlarm(((DataItemNCX)dataItem).getDiscR()); + data.setLeftVibrateAlarm(((DataItemNCX)dataItem).getVibL()); + data.setRightVibrateAlarm(((DataItemNCX)dataItem).getVibR()); + data.setUptime(LocalDateTime.parse(((DataItemNCX)dataItem).getTime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 采集时间 + data.setLogtime(LocalDateTime.parse(getUptime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 上报时间 + + dataList.add(data); + } + + return dataList; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java new file mode 100644 index 0000000..372ac73 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java @@ -0,0 +1,31 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.DataItem; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class DataItemNCX extends DataItem { + String lenL; // 左侧指示带长度 + String lenR; // 右侧指示带长度 + String ch4L; // 左侧甲烷浓度值 + String ch4R; // 右侧甲烷浓度值 + String bat; // 电池电压 + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String spare; // 备用 + String time; // 采集时间 + + @Override + public String toString() { + return "气体浓度值:" + "(" + ch4L + "," + ch4R + ")" + "%LEL;" + + "电池电压值:" + bat + "v;" + + "采样时间:" + time; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java new file mode 100644 index 0000000..b3bbcf4 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java @@ -0,0 +1,43 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.EventFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class EventFrameNCX extends EventFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + eventItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + EventItemNCX eventItem = new EventItemNCX(); + + eventItem.setSlope(dataObj.getString("SLOPING")); + eventItem.setDestroy(dataObj.getString("DESTROY")); + eventItem.setLeak(dataObj.getString("LEAK")); + eventItem.setDiscL(dataObj.getString("DISCL")); + eventItem.setDiscR(dataObj.getString("DISCR")); + eventItem.setVibL(dataObj.getString("VIBL")); + eventItem.setVibR(dataObj.getString("VIBR")); + eventItem.setTime(dataObj.getString("UPTIME")); + + eventItemList.add(eventItem); + } + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java new file mode 100644 index 0000000..1a560d0 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java @@ -0,0 +1,49 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.EventItem; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.commons.lang3.StringUtils; + +@EqualsAndHashCode(callSuper = true) +@Data +public class EventItemNCX extends EventItem { + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String time; // 采集时间 + + @Override + public String toString() { + String str = ""; + if (StringUtils.isNotBlank(slope) && slope.equalsIgnoreCase("1")) { + str += "[倾斜报警]"; + } + if (StringUtils.isNotBlank(destroy) && destroy.equalsIgnoreCase("1")) { + str += "[破坏报警]"; + } + if (StringUtils.isNotBlank(leak) && leak.equalsIgnoreCase("1")) { + str += "[甲烷泄漏报警]"; + } + if (StringUtils.isNotBlank(discL) && discL.equalsIgnoreCase("1")) { + str += "[左侧断线报警]"; + } + if (StringUtils.isNotBlank(discR) && discR.equalsIgnoreCase("1")) { + str += "[右侧断线报警]"; + } + if (StringUtils.isNotBlank(vibL) && vibL.equalsIgnoreCase("1")) { + str += "[左侧振动报警]"; + } + if (StringUtils.isNotBlank(vibR) && vibR.equalsIgnoreCase("1")) { + str += "[右侧振动报警]"; + } + str += "采样时间:" + time; + + return str; + + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java new file mode 100644 index 0000000..343c4d6 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java @@ -0,0 +1,37 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class InfoFrameNCX extends CasicFrame { + + String workMode; + String model; + String hwVersion; + String softVersion; + String sensorType; + + @Override + public String toString() { + return "设备编号: " + getDeviceCode() + "; " + + "设备工作模式: " + workMode + " ; " + + "设备型号: " + model + " ; " + + "版本号: " + hwVersion + ", " + softVersion + "; " + + "传感器类型: " + sensorType + " ; " + + "上报时间: " + getUptime(); + } + + @Override + public void parseMessageBody() { + workMode = getMessageBody().getString("WORKMODE"); + model = getMessageBody().getString("MODEL"); + hwVersion = getMessageBody().getString("HWVERSION"); + softVersion = getMessageBody().getString("SOFTVERSION"); + sensorType = getMessageBody().getString("SENSORTYPE"); + } +} diff --git a/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java new file mode 100644 index 0000000..e76fc86 --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java @@ -0,0 +1,14 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; + +public interface ISentinelFrameService { + + CasicFrame dataParse(String frame); + + String replyMessage(String deviceCode, String sequence); + + String doBuildCommand(CasicFrame cmd); + + void afterAction(CasicFrame frame); +} diff --git a/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java new file mode 100644 index 0000000..803ff0e --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java @@ -0,0 +1,109 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; +import com.casic.common.CasicFrameBuildFactory; +import com.casic.common.CasicProtocol; +import com.casic.common.general.DataFrame; +import com.casic.common.general.EventFrame; +import com.casic.common.general.ReplyFrame; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.model.DeviceWellView; +import com.casic.dao.service.IDataSentinelOtherService; +import com.casic.dao.service.IDeviceWellViewService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + + +@Service +@Slf4j +public class SentinelFrameServiceImpl implements ISentinelFrameService { + + @Resource + private CasicProtocol protocol; + + @Resource + IDataSentinelOtherService sentinelDataService; + + @Resource + IDeviceWellViewService deviceService; + + public CasicFrame dataParse(String frame) { + // 1. 判断帧结构 + boolean frameValid = protocol.checkFrame(frame); + if (frameValid) { + // 2. 获取帧结构中的关键字段信息 + String deviceId = protocol.getDeviceId(frame); + String deviceType = protocol.getDeviceType(frame); + String messageType = protocol.getMessageType(frame); + String messageBody = protocol.getMessageBody(frame).toUpperCase(); + String uptime = protocol.getUptime(frame); + String sequence = protocol.getMessageSequence(frame); + + String manufacturerCode = protocol.getManufacturerCode(frame); + CasicFrame sentinelFrame = CasicFrameBuildFactory.buildCasicFrame(messageType, manufacturerCode, deviceType); + + if (sentinelFrame != null) { + sentinelFrame.setDeviceCode(deviceId); + sentinelFrame.setUptime(uptime); + sentinelFrame.setMessageType(messageType); + sentinelFrame.setSequence(sequence); + + // 心跳类的消息不解析MessageBody + if (!sentinelFrame.getMessageType().equals("00")) { + sentinelFrame.setMessageBody(protocol.parseMessageBody(messageBody)); + sentinelFrame.parseMessageBody(); + } + + log.info("收到设备消息:{}", sentinelFrame); + return sentinelFrame; + } + } else { + log.error("消息帧解析异常"); + } + + return null; + } + + @Override + public String replyMessage(String deviceCode, String sequence) { + CasicFrame reply = new ReplyFrame(); + reply.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + reply.setDeviceCode(deviceCode); + reply.setSequence(sequence); + reply.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + return protocol.buildReplyFrameStr(reply); + } + + @Override + public String doBuildCommand(CasicFrame cmd) { + return protocol.buildFrameStr(cmd); + } + + @Override + public void afterAction(CasicFrame frame) { + // 数据消息帧 进行存库操作 + if (frame instanceof DataFrame) { + String devCode = frame.getDeviceCode(); + DeviceWellView devWellView = deviceService.getDeviceWellViewByDevCode(devCode); + String wellCode = ""; + if (devWellView != null) { + wellCode = devWellView.getWellCode(); + } + List dataList = ((DataFrame) frame).toDataModelList(); + if (dataList != null) { + for (Serializable item : dataList) { + DataMonitorPipeOther data = (DataMonitorPipeOther) item; + data.setWellCode(wellCode); + sentinelDataService.save(data); + } + } + } + } +} diff --git a/src/main/java/com/casic/tube/controller/TubeDataController.java b/src/main/java/com/casic/tube/controller/TubeDataController.java index 61486c5..4965449 100644 --- a/src/main/java/com/casic/tube/controller/TubeDataController.java +++ b/src/main/java/com/casic/tube/controller/TubeDataController.java @@ -2,8 +2,8 @@ import com.alibaba.fastjson.JSONObject; import com.casic.common.CasicFrame; -import com.casic.tube.frame.ConfigFrame; -import com.casic.tube.service.ITubeDataService; +import com.casic.common.general.ConfigFrame; +import com.casic.tube.service.ITubeFrameService; import com.casic.util.aep.AepCommandSend; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestBody; @@ -21,7 +21,7 @@ public class TubeDataController { @Resource - private ITubeDataService tubeDataService; + private ITubeFrameService frameService; @RequestMapping("/tube/data/recv") public Object dataRecv(@RequestBody Map map) { @@ -42,10 +42,10 @@ String frameStr = new String(baseBytes); // 根据协议进行解析 - CasicFrame frame = tubeDataService.dataParse(frameStr); + CasicFrame frame = frameService.dataParse(frameStr); // 存库 - tubeDataService.afterAction(frame); + frameService.afterAction(frame); retObj.put("code", 200); retObj.put("success", true); @@ -74,7 +74,7 @@ messageBody.put("datas", map.get("cmdList")); cmdFrame.setMessageBody(messageBody); - String frameStr = tubeDataService.doBuildCommand(cmdFrame); + String frameStr = frameService.doBuildCommand(cmdFrame); // TODO-LIST // 这三个参数根据设备编号从数据库中取 diff --git a/src/main/java/com/casic/tube/frame/ConfigFrame.java b/src/main/java/com/casic/tube/frame/ConfigFrame.java deleted file mode 100644 index 883dad6..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigFrame.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigFrame extends CasicFrame { - - public ConfigFrame() { - setSequence("01"); // 默认序号 - setControl("1"); // 默认为不需要分包 - setMessageType("52"); // 消息大类 52 = SetRequest - } -} diff --git a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java b/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java deleted file mode 100644 index a419145..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigResponseFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "03"; - final String MESSAGE_TYPE_STRING = "SetResponse"; - final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "指令序号" + getSequence() + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/DataFrame.java b/src/main/java/com/casic/tube/frame/DataFrame.java deleted file mode 100644 index 97e07b8..0000000 --- a/src/main/java/com/casic/tube/frame/DataFrame.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import com.casic.dao.model.DataTubeOther; - -import java.util.List; - -public class DataFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "02"; - final String MESSAGE_TYPE_STRING = "Data/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "数据消息/管盯"; - - public List dataItemList; - - public List toDataModelList() { - return null; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append(";"); - builder.append("上报时间:").append(getUptime()).append(";"); - for (DataItem dataItem : dataItemList) { - builder.append("["); - builder.append(dataItem); - builder.append("],"); - } - builder.deleteCharAt(builder.length() - 1); - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/DataItem.java b/src/main/java/com/casic/tube/frame/DataItem.java deleted file mode 100644 index 4e9aceb..0000000 --- a/src/main/java/com/casic/tube/frame/DataItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class DataItem { -} diff --git a/src/main/java/com/casic/tube/frame/EventFrame.java b/src/main/java/com/casic/tube/frame/EventFrame.java deleted file mode 100644 index ea800b4..0000000 --- a/src/main/java/com/casic/tube/frame/EventFrame.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -import java.util.List; - -public class EventFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "01"; - final String MESSAGE_TYPE_STRING = "Event/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "事件消息/管盯"; - - public List eventItemList; - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append("; "); - builder.append("上报时间:").append(getUptime()).append("; "); - for (EventItem eventItem : eventItemList) { - builder.append("["); - builder.append(eventItem); - builder.append("],"); - } - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/EventItem.java b/src/main/java/com/casic/tube/frame/EventItem.java deleted file mode 100644 index a1245bf..0000000 --- a/src/main/java/com/casic/tube/frame/EventItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class EventItem { -} diff --git a/src/main/java/com/casic/tube/frame/HeartFrame.java b/src/main/java/com/casic/tube/frame/HeartFrame.java deleted file mode 100644 index af7e7a6..0000000 --- a/src/main/java/com/casic/tube/frame/HeartFrame.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; - -@Data -public class HeartFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "00"; - final String MESSAGE_TYPE_STRING = "OnlineRequest"; - final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/IMEIFrame.java b/src/main/java/com/casic/tube/frame/IMEIFrame.java deleted file mode 100644 index 9420620..0000000 --- a/src/main/java/com/casic/tube/frame/IMEIFrame.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; - -@Data -public class IMEIFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "05"; - final String MESSAGE_TYPE_STRING = "StartupRequest"; - final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; - - String imei; - String iccid; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "IMEI:" + imei + ";" + - "ICCID:" + iccid + - "}"; - } - - @Override - public void parseMessageBody() { - imei = getMessageBody().getString("IMEI"); - iccid = getMessageBody().getString("ICCID"); - } -} diff --git a/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java b/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java index 50e8a2b..47bf4d6 100644 --- a/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java @@ -3,11 +3,12 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.casic.dao.model.DataTubeOther; -import com.casic.tube.frame.DataFrame; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -19,7 +20,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override @@ -43,8 +45,8 @@ } @Override - public List toDataModelList() { - List dataList = new ArrayList<>(); + public List toDataModelList() { + List dataList = new ArrayList<>(); for (DataItem dataItem : dataItemList) { DataTubeOther data = new DataTubeOther(); diff --git a/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java b/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java index 8d09b10..75e94c7 100644 --- a/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.brs; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java b/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java index 9026b4c..2e5c145 100644 --- a/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java @@ -2,14 +2,11 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.casic.common.CasicFrame; -import com.casic.tube.frame.EventFrame; -import com.casic.tube.frame.EventItem; +import com.casic.common.general.EventFrame; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; -import java.util.List; @Data @Slf4j @@ -17,7 +14,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override diff --git a/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java b/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java index 6c8146c..1792320 100644 --- a/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.brs; -import com.casic.tube.frame.EventItem; +import com.casic.common.general.EventItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java b/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java index e6e541c..b05b358 100644 --- a/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java @@ -3,11 +3,12 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.casic.dao.model.DataTubeOther; -import com.casic.tube.frame.DataFrame; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -19,7 +20,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override @@ -43,8 +45,8 @@ } @Override - public List toDataModelList() { - List dataList = new ArrayList<>(); + public List toDataModelList() { + List dataList = new ArrayList<>(); for (DataItem dataItem : dataItemList) { DataTubeOther data = new DataTubeOther(); diff --git a/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java b/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java index 0aa9bab..e875f2a 100644 --- a/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.mhk; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java b/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java index 9aea120..ec2d005 100644 --- a/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java @@ -2,13 +2,11 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.casic.common.CasicFrame; -import com.casic.tube.frame.EventFrame; +import com.casic.common.general.EventFrame; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; -import java.util.List; @Data @Slf4j @@ -16,7 +14,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override diff --git a/src/main/java/com/casic/tube/frame/mhk/EventItemMHK.java b/src/main/java/com/casic/tube/frame/mhk/EventItemMHK.java index 8f6a536..e5ffed6 100644 --- a/src/main/java/com/casic/tube/frame/mhk/EventItemMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/EventItemMHK.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.mhk; -import com.casic.tube.frame.EventItem; +import com.casic.common.general.EventItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/tp/DataFrameHTTP.java b/src/main/java/com/casic/tube/frame/tp/DataFrameHTTP.java index 23df423..69b7c1f 100644 --- a/src/main/java/com/casic/tube/frame/tp/DataFrameHTTP.java +++ b/src/main/java/com/casic/tube/frame/tp/DataFrameHTTP.java @@ -3,11 +3,12 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.casic.dao.model.DataTubeOther; -import com.casic.tube.frame.DataFrame; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -18,6 +19,12 @@ public class DataFrameHTTP extends DataFrame { @Override + public String toString(){ + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); + } + + @Override public void parseMessageBody() { JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); dataItemList = new ArrayList<>(); @@ -40,8 +47,8 @@ } @Override - public List toDataModelList() { - List dataList = new ArrayList<>(); + public List toDataModelList() { + List dataList = new ArrayList<>(); for (DataItem dataItem : dataItemList) { DataTubeOther data = new DataTubeOther(); diff --git a/src/main/java/com/casic/tube/frame/tp/DataItemHTTP.java b/src/main/java/com/casic/tube/frame/tp/DataItemHTTP.java index e5281eb..49d7c87 100644 --- a/src/main/java/com/casic/tube/frame/tp/DataItemHTTP.java +++ b/src/main/java/com/casic/tube/frame/tp/DataItemHTTP.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.tp; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/tube/protocol/CasicTubeProtocolImpl.java deleted file mode 100644 index 4fdd78c..0000000 --- a/src/main/java/com/casic/tube/protocol/CasicTubeProtocolImpl.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.casic.tube.protocol; - -import com.alibaba.fastjson.JSONObject; -import com.casic.common.CasicFrame; -import com.casic.common.CasicProtocol; -import org.springframework.stereotype.Component; - -@Component -public class CasicTubeProtocolImpl implements CasicProtocol { - @Override - public boolean checkFrame(String frame) { - boolean valid = checkFrameHeaderAndTail(frame); - if (valid) { - valid = checkFrameLength(frame); - } - - return valid; - } - - private boolean checkFrameHeaderAndTail(String frame) { - return (frame.substring(0, 2).equalsIgnoreCase("AA")) && - (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); - } - - private boolean checkFrameLength(String frame) { - String lengthStr = frame.substring(4, 7); - int length = Integer.parseInt(lengthStr); - - return frame.length() == length + 9; - } - - @Override - public String getDeviceType(String frame) { - return frame.substring(7, 9); - } - - @Override - public String getDeviceId(String frame) { - return frame.substring(9, 21); - } - - @Override - public String getManufacturerCode(String frame) { - return frame.substring(11, 13); - } - - @Override - public String getMessageType(String frame) { - return frame.substring(21, 23); - } - - @Override - public String getMessageBody(String frame) { - return frame.substring(26, frame.length() - 16); - } - - @Override - public JSONObject parseMessageBody(String messageBody) { - return JSONObject.parseObject(messageBody); - } - - @Override - public String getUptime(String frame) { - return frame.substring(frame.length() - 16, frame.length() - 2); - } - - @Override - public String buildFrameStr(CasicFrame frame) { - StringBuilder builder = new StringBuilder(); - - builder.append(frame.getDeviceType()); - builder.append(frame.getDeviceCode()); - builder.append(frame.getMessageType()); - builder.append(frame.getSequence()); - builder.append(frame.getControl()); - builder.append(frame.getMessageBody().toJSONString()); - builder.append(frame.getUptime()); - - builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 - builder.insert(0, frame.getVersion()); - builder.insert(0, frame.getHEADER()); - builder.append(frame.getTAIL()); - - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/service/ITubeDataService.java b/src/main/java/com/casic/tube/service/ITubeDataService.java deleted file mode 100644 index c9dafea..0000000 --- a/src/main/java/com/casic/tube/service/ITubeDataService.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.casic.tube.service; - -import com.alibaba.fastjson.JSONObject; -import com.casic.common.CasicFrame; - -public interface ITubeDataService { - - CasicFrame dataParse(String frame); - - String doBuildCommand(CasicFrame cmd); - - void afterAction(CasicFrame frame); -} diff --git a/src/main/java/com/casic/tube/service/ITubeFrameService.java b/src/main/java/com/casic/tube/service/ITubeFrameService.java new file mode 100644 index 0000000..1ba209c --- /dev/null +++ b/src/main/java/com/casic/tube/service/ITubeFrameService.java @@ -0,0 +1,12 @@ +package com.casic.tube.service; + +import com.casic.common.CasicFrame; + +public interface ITubeFrameService { + + CasicFrame dataParse(String frame); + + String doBuildCommand(CasicFrame cmd); + + void afterAction(CasicFrame frame); +} diff --git a/src/main/java/com/casic/tube/service/TubeDataServiceImpl.java b/src/main/java/com/casic/tube/service/TubeDataServiceImpl.java deleted file mode 100644 index 46d049d..0000000 --- a/src/main/java/com/casic/tube/service/TubeDataServiceImpl.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.casic.tube.service; - -import com.casic.common.CasicFrame; -import com.casic.common.CasicFrameBuildFactory; -import com.casic.common.CasicProtocol; -import com.casic.dao.model.DataTubeOther; -import com.casic.dao.model.DeviceWellView; -import com.casic.dao.service.IDataTubeOtherService; -import com.casic.dao.service.IDeviceWellViewService; -import com.casic.tube.frame.DataFrame; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -import javax.annotation.Resource; -import java.util.List; - - -@Service -@Slf4j -public class TubeDataServiceImpl implements ITubeDataService { - - @Resource - private CasicProtocol tubeProtocol; - - @Resource - IDataTubeOtherService tubeDataService; - - @Resource - IDeviceWellViewService deviceService; - - public CasicFrame dataParse(String frame) { - // 1. 判断帧结构 - boolean frameValid = tubeProtocol.checkFrame(frame); - if (frameValid) { - // 2. 获取帧结构中的关键字段信息 - String deviceId = tubeProtocol.getDeviceId(frame); - String messageType = tubeProtocol.getMessageType(frame); - String messageBody = tubeProtocol.getMessageBody(frame).toUpperCase(); - String uptime = tubeProtocol.getUptime(frame); - - String manufacturerCode = tubeProtocol.getManufacturerCode(frame); - CasicFrame tubeFrame = CasicFrameBuildFactory.buildCasicFrame(messageType, manufacturerCode); - - if (tubeFrame != null) { - tubeFrame.setDeviceCode(deviceId); - tubeFrame.setUptime(uptime); - tubeFrame.setMessageType(messageType); - - // 心跳类的消息不解析MessageBody - if (!tubeFrame.getMessageType().equals("00")) { - tubeFrame.setMessageBody(tubeProtocol.parseMessageBody(messageBody)); - tubeFrame.parseMessageBody(); - } - - log.info("收到设备消息:{}", tubeFrame); - return tubeFrame; - } - } else { - log.error("消息帧解析异常"); - } - - return null; - } - - @Override - public String doBuildCommand(CasicFrame cmd) { - return tubeProtocol.buildFrameStr(cmd); - } - - @Override - public void afterAction(CasicFrame frame) { - // 数据消息帧 进行存库操作 - if (frame instanceof DataFrame) { - String devCode = frame.getDeviceCode(); - DeviceWellView devWellView = deviceService.getDeviceWellViewByDevCode(devCode); - String wellCode = ""; - if (devWellView != null) { - wellCode = devWellView.getWellCode(); - } - List dataList = ((DataFrame) frame).toDataModelList(); - if (dataList != null) { - for (DataTubeOther data : dataList) { - data.setWellCode(wellCode); - tubeDataService.save(data); - } - } - } - } -} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java new file mode 100644 index 0000000..95d2bd4 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java @@ -0,0 +1,8 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.DataMonitorPipeOther; + +public interface IDataSentinelOtherService extends IService { + +} diff --git a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java index d6b1200..0290829 100644 --- a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java +++ b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java @@ -1,7 +1,6 @@ package com.casic.dao.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.dao.model.DataTubeOther; import com.casic.dao.model.DeviceWellView; public interface IDeviceWellViewService extends IService { diff --git a/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java new file mode 100644 index 0000000..be34f77 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java @@ -0,0 +1,16 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.BusDeviceMapper; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import org.springframework.stereotype.Service; + +@Service +public class BusDeviceServiceImpl extends ServiceImpl implements IBusDeviceService { + + @Override + public BusDevice getDeviceByCode(String devCode) { + return baseMapper.getOneByDevCode(devCode); + } +} diff --git a/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java new file mode 100644 index 0000000..0db2007 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java @@ -0,0 +1,11 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.DataSentinelOtherMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.service.IDataSentinelOtherService; +import org.springframework.stereotype.Service; + +@Service +public class DataSentinelOtherServiceImpl extends ServiceImpl implements IDataSentinelOtherService { +} diff --git a/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java new file mode 100644 index 0000000..d8c5ef2 --- /dev/null +++ b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java @@ -0,0 +1,111 @@ +package com.casic.protocol; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.CasicProtocol; +import org.springframework.stereotype.Component; + +@Component +public class CasicTubeProtocolImpl implements CasicProtocol { + @Override + public boolean checkFrame(String frame) { + boolean valid = checkFrameHeaderAndTail(frame); + if (valid) { + valid = checkFrameLength(frame); + } + + return valid; + } + + private boolean checkFrameHeaderAndTail(String frame) { + return (frame.substring(0, 2).equalsIgnoreCase("AA")) && + (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); + } + + private boolean checkFrameLength(String frame) { + String lengthStr = frame.substring(4, 7); + int length = Integer.parseInt(lengthStr); + + return frame.length() == length + 9; + } + + @Override + public String getDeviceType(String frame) { + return frame.substring(7, 9); + } + + @Override + public String getDeviceId(String frame) { + return frame.substring(9, 21); + } + + @Override + public String getManufacturerCode(String frame) { + return frame.substring(11, 13); + } + + @Override + public String getMessageType(String frame) { + return frame.substring(21, 23); + } + + @Override + public String getMessageSequence(String frame) { + return frame.substring(23, 25); + } + + @Override + public String getMessageBody(String frame) { + return frame.substring(26, frame.length() - 16); + } + + @Override + public JSONObject parseMessageBody(String messageBody) { + return JSONObject.parseObject(messageBody); + } + + @Override + public String getUptime(String frame) { + return frame.substring(frame.length() - 16, frame.length() - 2); + } + + @Override + public String buildFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append(frame.getMessageBody().toJSONString()); + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } + + @Override + public String buildReplyFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append("00"); // 消息响应类消息 消息体为00 + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/senitnel/controller/SentinelDataController.java b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java new file mode 100644 index 0000000..633c072 --- /dev/null +++ b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java @@ -0,0 +1,120 @@ +package com.casic.senitnel.controller; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.general.ConfigFrame; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import com.casic.senitnel.service.ISentinelFrameService; +import com.casic.util.aep.AepCommandSend; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Base64; +import java.util.Map; + +@Slf4j +@RestController +public class SentinelDataController { + + @Resource + private ISentinelFrameService frameService; + + @Resource + private IBusDeviceService deviceService; + + @RequestMapping("/sentinel/data/recv") + public Object dataRecv(@RequestBody Map map) { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + + JSONObject recvObj = (JSONObject) JSONObject.toJSON(map); + if (recvObj.containsKey("payload")) { + JSONObject payload = recvObj.getJSONObject("payload"); + String value = payload.getString("APPdata"); + + if (value.isEmpty()) { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } else { + byte[] baseBytes = Base64.getDecoder().decode(value); + String frameStr = new String(baseBytes); + + // 根据协议进行解析 + CasicFrame frame = frameService.dataParse(frameStr); + + if (frame != null) { + // 回复响应 + String replyFrameStr = frameService.replyMessage(frame.getDeviceCode(), frame.getSequence()); + + // 从数据库中获取master-api-key 回复响应消息 + BusDevice device = deviceService.getDeviceByCode(frame.getDeviceCode()); + if (device != null && StringUtils.isNotBlank(device.getMasterApiKey())) { + String masterApiKey = device.getMasterApiKey(); + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + + try { + int code = aepCommandSend.handleAndReply(replyFrameStr); + } catch (Exception ex) { + log.error("向设备回复响应异常:{}", ex.getMessage()); + } + } + + // 存库 + frameService.afterAction(frame); + } + + retObj.put("code", 200); + retObj.put("success", true); + } + } else { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } + + return retObj; + } + + @RequestMapping("/sentinel/config/send") + public Object configSend(@RequestBody Map map) throws Exception { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + CasicFrame cmdFrame = new ConfigFrame(); + cmdFrame.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + cmdFrame.setDeviceCode((String) map.get("devCode")); + cmdFrame.setSequence("01"); + cmdFrame.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + JSONObject messageBody = new JSONObject(); + messageBody.put("datas", map.get("cmdList")); + cmdFrame.setMessageBody(messageBody); + + String frameStr = frameService.doBuildCommand(cmdFrame); + + // TODO-LIST + // 这三个参数根据设备编号从数据库中取 + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + String masterApiKey = (String) map.get("masterApiKey"); + + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + int code = aepCommandSend.handleAndReply(frameStr); + + retObj.put("code", 200); + retObj.put("success", true); + retObj.put("AEPRetCode", code); + return retObj; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java new file mode 100644 index 0000000..368af03 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java @@ -0,0 +1,82 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; +import com.casic.dao.model.DataMonitorPipeOther; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class DataFrameNCX extends DataFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + dataItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + DataItemNCX dataItem = new DataItemNCX(); + + dataItem.setLenL(dataObj.getString("LENGL")); + dataItem.setLenR(dataObj.getString("LENGR")); + dataItem.setBat(dataObj.getString("BAT")); + dataItem.setCh4L(dataObj.getString("CH4L")); + dataItem.setCh4R(dataObj.getString("CH4R")); + dataItem.setSlope(dataObj.getString("SLOPING")); + dataItem.setDestroy(dataObj.getString("DESTROY")); + dataItem.setLeak(dataObj.getString("LEAK")); + dataItem.setDiscL(dataObj.getString("DISCL")); + dataItem.setDiscR(dataObj.getString("DISCR")); + dataItem.setVibL(dataObj.getString("VIBL")); + dataItem.setVibR(dataObj.getString("VIBR")); + dataItem.setTime(dataObj.getString("UPTIME")); + + dataItemList.add(dataItem); + } + } + + @Override + public List toDataModelList() { + List dataList = new ArrayList<>(); + for (DataItem dataItem : dataItemList) { + DataMonitorPipeOther data = new DataMonitorPipeOther(); + + data.setDevcode(getDeviceCode()); + data.setLeftLength(((DataItemNCX)dataItem).getLenL()); + data.setRightLength(((DataItemNCX)dataItem).getLenR()); + data.setLeftGas(((DataItemNCX)dataItem).getCh4L()); + data.setRightGas(((DataItemNCX)dataItem).getCh4R()); + data.setVbat(((DataItemNCX)dataItem).getBat()); + data.setPipeInclineAlarm(((DataItemNCX)dataItem).getSlope()); + data.setPipeBreakAlarm(((DataItemNCX)dataItem).getDestroy()); + data.setGasAlarm(((DataItemNCX)dataItem).getLeak()); + data.setLeftOfflineAlarm(((DataItemNCX)dataItem).getDiscL()); + data.setRightOfflineAlarm(((DataItemNCX)dataItem).getDiscR()); + data.setLeftVibrateAlarm(((DataItemNCX)dataItem).getVibL()); + data.setRightVibrateAlarm(((DataItemNCX)dataItem).getVibR()); + data.setUptime(LocalDateTime.parse(((DataItemNCX)dataItem).getTime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 采集时间 + data.setLogtime(LocalDateTime.parse(getUptime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 上报时间 + + dataList.add(data); + } + + return dataList; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java new file mode 100644 index 0000000..372ac73 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java @@ -0,0 +1,31 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.DataItem; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class DataItemNCX extends DataItem { + String lenL; // 左侧指示带长度 + String lenR; // 右侧指示带长度 + String ch4L; // 左侧甲烷浓度值 + String ch4R; // 右侧甲烷浓度值 + String bat; // 电池电压 + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String spare; // 备用 + String time; // 采集时间 + + @Override + public String toString() { + return "气体浓度值:" + "(" + ch4L + "," + ch4R + ")" + "%LEL;" + + "电池电压值:" + bat + "v;" + + "采样时间:" + time; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java new file mode 100644 index 0000000..b3bbcf4 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java @@ -0,0 +1,43 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.EventFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class EventFrameNCX extends EventFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + eventItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + EventItemNCX eventItem = new EventItemNCX(); + + eventItem.setSlope(dataObj.getString("SLOPING")); + eventItem.setDestroy(dataObj.getString("DESTROY")); + eventItem.setLeak(dataObj.getString("LEAK")); + eventItem.setDiscL(dataObj.getString("DISCL")); + eventItem.setDiscR(dataObj.getString("DISCR")); + eventItem.setVibL(dataObj.getString("VIBL")); + eventItem.setVibR(dataObj.getString("VIBR")); + eventItem.setTime(dataObj.getString("UPTIME")); + + eventItemList.add(eventItem); + } + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java new file mode 100644 index 0000000..1a560d0 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java @@ -0,0 +1,49 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.EventItem; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.commons.lang3.StringUtils; + +@EqualsAndHashCode(callSuper = true) +@Data +public class EventItemNCX extends EventItem { + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String time; // 采集时间 + + @Override + public String toString() { + String str = ""; + if (StringUtils.isNotBlank(slope) && slope.equalsIgnoreCase("1")) { + str += "[倾斜报警]"; + } + if (StringUtils.isNotBlank(destroy) && destroy.equalsIgnoreCase("1")) { + str += "[破坏报警]"; + } + if (StringUtils.isNotBlank(leak) && leak.equalsIgnoreCase("1")) { + str += "[甲烷泄漏报警]"; + } + if (StringUtils.isNotBlank(discL) && discL.equalsIgnoreCase("1")) { + str += "[左侧断线报警]"; + } + if (StringUtils.isNotBlank(discR) && discR.equalsIgnoreCase("1")) { + str += "[右侧断线报警]"; + } + if (StringUtils.isNotBlank(vibL) && vibL.equalsIgnoreCase("1")) { + str += "[左侧振动报警]"; + } + if (StringUtils.isNotBlank(vibR) && vibR.equalsIgnoreCase("1")) { + str += "[右侧振动报警]"; + } + str += "采样时间:" + time; + + return str; + + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java new file mode 100644 index 0000000..343c4d6 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java @@ -0,0 +1,37 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class InfoFrameNCX extends CasicFrame { + + String workMode; + String model; + String hwVersion; + String softVersion; + String sensorType; + + @Override + public String toString() { + return "设备编号: " + getDeviceCode() + "; " + + "设备工作模式: " + workMode + " ; " + + "设备型号: " + model + " ; " + + "版本号: " + hwVersion + ", " + softVersion + "; " + + "传感器类型: " + sensorType + " ; " + + "上报时间: " + getUptime(); + } + + @Override + public void parseMessageBody() { + workMode = getMessageBody().getString("WORKMODE"); + model = getMessageBody().getString("MODEL"); + hwVersion = getMessageBody().getString("HWVERSION"); + softVersion = getMessageBody().getString("SOFTVERSION"); + sensorType = getMessageBody().getString("SENSORTYPE"); + } +} diff --git a/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java new file mode 100644 index 0000000..e76fc86 --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java @@ -0,0 +1,14 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; + +public interface ISentinelFrameService { + + CasicFrame dataParse(String frame); + + String replyMessage(String deviceCode, String sequence); + + String doBuildCommand(CasicFrame cmd); + + void afterAction(CasicFrame frame); +} diff --git a/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java new file mode 100644 index 0000000..803ff0e --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java @@ -0,0 +1,109 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; +import com.casic.common.CasicFrameBuildFactory; +import com.casic.common.CasicProtocol; +import com.casic.common.general.DataFrame; +import com.casic.common.general.EventFrame; +import com.casic.common.general.ReplyFrame; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.model.DeviceWellView; +import com.casic.dao.service.IDataSentinelOtherService; +import com.casic.dao.service.IDeviceWellViewService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + + +@Service +@Slf4j +public class SentinelFrameServiceImpl implements ISentinelFrameService { + + @Resource + private CasicProtocol protocol; + + @Resource + IDataSentinelOtherService sentinelDataService; + + @Resource + IDeviceWellViewService deviceService; + + public CasicFrame dataParse(String frame) { + // 1. 判断帧结构 + boolean frameValid = protocol.checkFrame(frame); + if (frameValid) { + // 2. 获取帧结构中的关键字段信息 + String deviceId = protocol.getDeviceId(frame); + String deviceType = protocol.getDeviceType(frame); + String messageType = protocol.getMessageType(frame); + String messageBody = protocol.getMessageBody(frame).toUpperCase(); + String uptime = protocol.getUptime(frame); + String sequence = protocol.getMessageSequence(frame); + + String manufacturerCode = protocol.getManufacturerCode(frame); + CasicFrame sentinelFrame = CasicFrameBuildFactory.buildCasicFrame(messageType, manufacturerCode, deviceType); + + if (sentinelFrame != null) { + sentinelFrame.setDeviceCode(deviceId); + sentinelFrame.setUptime(uptime); + sentinelFrame.setMessageType(messageType); + sentinelFrame.setSequence(sequence); + + // 心跳类的消息不解析MessageBody + if (!sentinelFrame.getMessageType().equals("00")) { + sentinelFrame.setMessageBody(protocol.parseMessageBody(messageBody)); + sentinelFrame.parseMessageBody(); + } + + log.info("收到设备消息:{}", sentinelFrame); + return sentinelFrame; + } + } else { + log.error("消息帧解析异常"); + } + + return null; + } + + @Override + public String replyMessage(String deviceCode, String sequence) { + CasicFrame reply = new ReplyFrame(); + reply.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + reply.setDeviceCode(deviceCode); + reply.setSequence(sequence); + reply.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + return protocol.buildReplyFrameStr(reply); + } + + @Override + public String doBuildCommand(CasicFrame cmd) { + return protocol.buildFrameStr(cmd); + } + + @Override + public void afterAction(CasicFrame frame) { + // 数据消息帧 进行存库操作 + if (frame instanceof DataFrame) { + String devCode = frame.getDeviceCode(); + DeviceWellView devWellView = deviceService.getDeviceWellViewByDevCode(devCode); + String wellCode = ""; + if (devWellView != null) { + wellCode = devWellView.getWellCode(); + } + List dataList = ((DataFrame) frame).toDataModelList(); + if (dataList != null) { + for (Serializable item : dataList) { + DataMonitorPipeOther data = (DataMonitorPipeOther) item; + data.setWellCode(wellCode); + sentinelDataService.save(data); + } + } + } + } +} diff --git a/src/main/java/com/casic/tube/controller/TubeDataController.java b/src/main/java/com/casic/tube/controller/TubeDataController.java index 61486c5..4965449 100644 --- a/src/main/java/com/casic/tube/controller/TubeDataController.java +++ b/src/main/java/com/casic/tube/controller/TubeDataController.java @@ -2,8 +2,8 @@ import com.alibaba.fastjson.JSONObject; import com.casic.common.CasicFrame; -import com.casic.tube.frame.ConfigFrame; -import com.casic.tube.service.ITubeDataService; +import com.casic.common.general.ConfigFrame; +import com.casic.tube.service.ITubeFrameService; import com.casic.util.aep.AepCommandSend; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestBody; @@ -21,7 +21,7 @@ public class TubeDataController { @Resource - private ITubeDataService tubeDataService; + private ITubeFrameService frameService; @RequestMapping("/tube/data/recv") public Object dataRecv(@RequestBody Map map) { @@ -42,10 +42,10 @@ String frameStr = new String(baseBytes); // 根据协议进行解析 - CasicFrame frame = tubeDataService.dataParse(frameStr); + CasicFrame frame = frameService.dataParse(frameStr); // 存库 - tubeDataService.afterAction(frame); + frameService.afterAction(frame); retObj.put("code", 200); retObj.put("success", true); @@ -74,7 +74,7 @@ messageBody.put("datas", map.get("cmdList")); cmdFrame.setMessageBody(messageBody); - String frameStr = tubeDataService.doBuildCommand(cmdFrame); + String frameStr = frameService.doBuildCommand(cmdFrame); // TODO-LIST // 这三个参数根据设备编号从数据库中取 diff --git a/src/main/java/com/casic/tube/frame/ConfigFrame.java b/src/main/java/com/casic/tube/frame/ConfigFrame.java deleted file mode 100644 index 883dad6..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigFrame.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigFrame extends CasicFrame { - - public ConfigFrame() { - setSequence("01"); // 默认序号 - setControl("1"); // 默认为不需要分包 - setMessageType("52"); // 消息大类 52 = SetRequest - } -} diff --git a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java b/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java deleted file mode 100644 index a419145..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigResponseFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "03"; - final String MESSAGE_TYPE_STRING = "SetResponse"; - final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "指令序号" + getSequence() + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/DataFrame.java b/src/main/java/com/casic/tube/frame/DataFrame.java deleted file mode 100644 index 97e07b8..0000000 --- a/src/main/java/com/casic/tube/frame/DataFrame.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import com.casic.dao.model.DataTubeOther; - -import java.util.List; - -public class DataFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "02"; - final String MESSAGE_TYPE_STRING = "Data/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "数据消息/管盯"; - - public List dataItemList; - - public List toDataModelList() { - return null; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append(";"); - builder.append("上报时间:").append(getUptime()).append(";"); - for (DataItem dataItem : dataItemList) { - builder.append("["); - builder.append(dataItem); - builder.append("],"); - } - builder.deleteCharAt(builder.length() - 1); - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/DataItem.java b/src/main/java/com/casic/tube/frame/DataItem.java deleted file mode 100644 index 4e9aceb..0000000 --- a/src/main/java/com/casic/tube/frame/DataItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class DataItem { -} diff --git a/src/main/java/com/casic/tube/frame/EventFrame.java b/src/main/java/com/casic/tube/frame/EventFrame.java deleted file mode 100644 index ea800b4..0000000 --- a/src/main/java/com/casic/tube/frame/EventFrame.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -import java.util.List; - -public class EventFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "01"; - final String MESSAGE_TYPE_STRING = "Event/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "事件消息/管盯"; - - public List eventItemList; - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append("; "); - builder.append("上报时间:").append(getUptime()).append("; "); - for (EventItem eventItem : eventItemList) { - builder.append("["); - builder.append(eventItem); - builder.append("],"); - } - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/EventItem.java b/src/main/java/com/casic/tube/frame/EventItem.java deleted file mode 100644 index a1245bf..0000000 --- a/src/main/java/com/casic/tube/frame/EventItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class EventItem { -} diff --git a/src/main/java/com/casic/tube/frame/HeartFrame.java b/src/main/java/com/casic/tube/frame/HeartFrame.java deleted file mode 100644 index af7e7a6..0000000 --- a/src/main/java/com/casic/tube/frame/HeartFrame.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; - -@Data -public class HeartFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "00"; - final String MESSAGE_TYPE_STRING = "OnlineRequest"; - final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/IMEIFrame.java b/src/main/java/com/casic/tube/frame/IMEIFrame.java deleted file mode 100644 index 9420620..0000000 --- a/src/main/java/com/casic/tube/frame/IMEIFrame.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; - -@Data -public class IMEIFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "05"; - final String MESSAGE_TYPE_STRING = "StartupRequest"; - final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; - - String imei; - String iccid; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "IMEI:" + imei + ";" + - "ICCID:" + iccid + - "}"; - } - - @Override - public void parseMessageBody() { - imei = getMessageBody().getString("IMEI"); - iccid = getMessageBody().getString("ICCID"); - } -} diff --git a/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java b/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java index 50e8a2b..47bf4d6 100644 --- a/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java @@ -3,11 +3,12 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.casic.dao.model.DataTubeOther; -import com.casic.tube.frame.DataFrame; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -19,7 +20,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override @@ -43,8 +45,8 @@ } @Override - public List toDataModelList() { - List dataList = new ArrayList<>(); + public List toDataModelList() { + List dataList = new ArrayList<>(); for (DataItem dataItem : dataItemList) { DataTubeOther data = new DataTubeOther(); diff --git a/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java b/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java index 8d09b10..75e94c7 100644 --- a/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.brs; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java b/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java index 9026b4c..2e5c145 100644 --- a/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java @@ -2,14 +2,11 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.casic.common.CasicFrame; -import com.casic.tube.frame.EventFrame; -import com.casic.tube.frame.EventItem; +import com.casic.common.general.EventFrame; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; -import java.util.List; @Data @Slf4j @@ -17,7 +14,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override diff --git a/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java b/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java index 6c8146c..1792320 100644 --- a/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.brs; -import com.casic.tube.frame.EventItem; +import com.casic.common.general.EventItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java b/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java index e6e541c..b05b358 100644 --- a/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java @@ -3,11 +3,12 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.casic.dao.model.DataTubeOther; -import com.casic.tube.frame.DataFrame; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -19,7 +20,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override @@ -43,8 +45,8 @@ } @Override - public List toDataModelList() { - List dataList = new ArrayList<>(); + public List toDataModelList() { + List dataList = new ArrayList<>(); for (DataItem dataItem : dataItemList) { DataTubeOther data = new DataTubeOther(); diff --git a/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java b/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java index 0aa9bab..e875f2a 100644 --- a/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.mhk; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java b/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java index 9aea120..ec2d005 100644 --- a/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java @@ -2,13 +2,11 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.casic.common.CasicFrame; -import com.casic.tube.frame.EventFrame; +import com.casic.common.general.EventFrame; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; -import java.util.List; @Data @Slf4j @@ -16,7 +14,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override diff --git a/src/main/java/com/casic/tube/frame/mhk/EventItemMHK.java b/src/main/java/com/casic/tube/frame/mhk/EventItemMHK.java index 8f6a536..e5ffed6 100644 --- a/src/main/java/com/casic/tube/frame/mhk/EventItemMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/EventItemMHK.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.mhk; -import com.casic.tube.frame.EventItem; +import com.casic.common.general.EventItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/tp/DataFrameHTTP.java b/src/main/java/com/casic/tube/frame/tp/DataFrameHTTP.java index 23df423..69b7c1f 100644 --- a/src/main/java/com/casic/tube/frame/tp/DataFrameHTTP.java +++ b/src/main/java/com/casic/tube/frame/tp/DataFrameHTTP.java @@ -3,11 +3,12 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.casic.dao.model.DataTubeOther; -import com.casic.tube.frame.DataFrame; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -18,6 +19,12 @@ public class DataFrameHTTP extends DataFrame { @Override + public String toString(){ + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); + } + + @Override public void parseMessageBody() { JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); dataItemList = new ArrayList<>(); @@ -40,8 +47,8 @@ } @Override - public List toDataModelList() { - List dataList = new ArrayList<>(); + public List toDataModelList() { + List dataList = new ArrayList<>(); for (DataItem dataItem : dataItemList) { DataTubeOther data = new DataTubeOther(); diff --git a/src/main/java/com/casic/tube/frame/tp/DataItemHTTP.java b/src/main/java/com/casic/tube/frame/tp/DataItemHTTP.java index e5281eb..49d7c87 100644 --- a/src/main/java/com/casic/tube/frame/tp/DataItemHTTP.java +++ b/src/main/java/com/casic/tube/frame/tp/DataItemHTTP.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.tp; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/tube/protocol/CasicTubeProtocolImpl.java deleted file mode 100644 index 4fdd78c..0000000 --- a/src/main/java/com/casic/tube/protocol/CasicTubeProtocolImpl.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.casic.tube.protocol; - -import com.alibaba.fastjson.JSONObject; -import com.casic.common.CasicFrame; -import com.casic.common.CasicProtocol; -import org.springframework.stereotype.Component; - -@Component -public class CasicTubeProtocolImpl implements CasicProtocol { - @Override - public boolean checkFrame(String frame) { - boolean valid = checkFrameHeaderAndTail(frame); - if (valid) { - valid = checkFrameLength(frame); - } - - return valid; - } - - private boolean checkFrameHeaderAndTail(String frame) { - return (frame.substring(0, 2).equalsIgnoreCase("AA")) && - (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); - } - - private boolean checkFrameLength(String frame) { - String lengthStr = frame.substring(4, 7); - int length = Integer.parseInt(lengthStr); - - return frame.length() == length + 9; - } - - @Override - public String getDeviceType(String frame) { - return frame.substring(7, 9); - } - - @Override - public String getDeviceId(String frame) { - return frame.substring(9, 21); - } - - @Override - public String getManufacturerCode(String frame) { - return frame.substring(11, 13); - } - - @Override - public String getMessageType(String frame) { - return frame.substring(21, 23); - } - - @Override - public String getMessageBody(String frame) { - return frame.substring(26, frame.length() - 16); - } - - @Override - public JSONObject parseMessageBody(String messageBody) { - return JSONObject.parseObject(messageBody); - } - - @Override - public String getUptime(String frame) { - return frame.substring(frame.length() - 16, frame.length() - 2); - } - - @Override - public String buildFrameStr(CasicFrame frame) { - StringBuilder builder = new StringBuilder(); - - builder.append(frame.getDeviceType()); - builder.append(frame.getDeviceCode()); - builder.append(frame.getMessageType()); - builder.append(frame.getSequence()); - builder.append(frame.getControl()); - builder.append(frame.getMessageBody().toJSONString()); - builder.append(frame.getUptime()); - - builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 - builder.insert(0, frame.getVersion()); - builder.insert(0, frame.getHEADER()); - builder.append(frame.getTAIL()); - - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/service/ITubeDataService.java b/src/main/java/com/casic/tube/service/ITubeDataService.java deleted file mode 100644 index c9dafea..0000000 --- a/src/main/java/com/casic/tube/service/ITubeDataService.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.casic.tube.service; - -import com.alibaba.fastjson.JSONObject; -import com.casic.common.CasicFrame; - -public interface ITubeDataService { - - CasicFrame dataParse(String frame); - - String doBuildCommand(CasicFrame cmd); - - void afterAction(CasicFrame frame); -} diff --git a/src/main/java/com/casic/tube/service/ITubeFrameService.java b/src/main/java/com/casic/tube/service/ITubeFrameService.java new file mode 100644 index 0000000..1ba209c --- /dev/null +++ b/src/main/java/com/casic/tube/service/ITubeFrameService.java @@ -0,0 +1,12 @@ +package com.casic.tube.service; + +import com.casic.common.CasicFrame; + +public interface ITubeFrameService { + + CasicFrame dataParse(String frame); + + String doBuildCommand(CasicFrame cmd); + + void afterAction(CasicFrame frame); +} diff --git a/src/main/java/com/casic/tube/service/TubeDataServiceImpl.java b/src/main/java/com/casic/tube/service/TubeDataServiceImpl.java deleted file mode 100644 index 46d049d..0000000 --- a/src/main/java/com/casic/tube/service/TubeDataServiceImpl.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.casic.tube.service; - -import com.casic.common.CasicFrame; -import com.casic.common.CasicFrameBuildFactory; -import com.casic.common.CasicProtocol; -import com.casic.dao.model.DataTubeOther; -import com.casic.dao.model.DeviceWellView; -import com.casic.dao.service.IDataTubeOtherService; -import com.casic.dao.service.IDeviceWellViewService; -import com.casic.tube.frame.DataFrame; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -import javax.annotation.Resource; -import java.util.List; - - -@Service -@Slf4j -public class TubeDataServiceImpl implements ITubeDataService { - - @Resource - private CasicProtocol tubeProtocol; - - @Resource - IDataTubeOtherService tubeDataService; - - @Resource - IDeviceWellViewService deviceService; - - public CasicFrame dataParse(String frame) { - // 1. 判断帧结构 - boolean frameValid = tubeProtocol.checkFrame(frame); - if (frameValid) { - // 2. 获取帧结构中的关键字段信息 - String deviceId = tubeProtocol.getDeviceId(frame); - String messageType = tubeProtocol.getMessageType(frame); - String messageBody = tubeProtocol.getMessageBody(frame).toUpperCase(); - String uptime = tubeProtocol.getUptime(frame); - - String manufacturerCode = tubeProtocol.getManufacturerCode(frame); - CasicFrame tubeFrame = CasicFrameBuildFactory.buildCasicFrame(messageType, manufacturerCode); - - if (tubeFrame != null) { - tubeFrame.setDeviceCode(deviceId); - tubeFrame.setUptime(uptime); - tubeFrame.setMessageType(messageType); - - // 心跳类的消息不解析MessageBody - if (!tubeFrame.getMessageType().equals("00")) { - tubeFrame.setMessageBody(tubeProtocol.parseMessageBody(messageBody)); - tubeFrame.parseMessageBody(); - } - - log.info("收到设备消息:{}", tubeFrame); - return tubeFrame; - } - } else { - log.error("消息帧解析异常"); - } - - return null; - } - - @Override - public String doBuildCommand(CasicFrame cmd) { - return tubeProtocol.buildFrameStr(cmd); - } - - @Override - public void afterAction(CasicFrame frame) { - // 数据消息帧 进行存库操作 - if (frame instanceof DataFrame) { - String devCode = frame.getDeviceCode(); - DeviceWellView devWellView = deviceService.getDeviceWellViewByDevCode(devCode); - String wellCode = ""; - if (devWellView != null) { - wellCode = devWellView.getWellCode(); - } - List dataList = ((DataFrame) frame).toDataModelList(); - if (dataList != null) { - for (DataTubeOther data : dataList) { - data.setWellCode(wellCode); - tubeDataService.save(data); - } - } - } - } -} diff --git a/src/main/java/com/casic/tube/service/TubeFrameServiceImpl.java b/src/main/java/com/casic/tube/service/TubeFrameServiceImpl.java new file mode 100644 index 0000000..5eaa12b --- /dev/null +++ b/src/main/java/com/casic/tube/service/TubeFrameServiceImpl.java @@ -0,0 +1,92 @@ +package com.casic.tube.service; + +import com.casic.common.CasicFrame; +import com.casic.common.CasicFrameBuildFactory; +import com.casic.common.CasicProtocol; +import com.casic.dao.model.DataTubeOther; +import com.casic.dao.model.DeviceWellView; +import com.casic.dao.service.IDataTubeOtherService; +import com.casic.dao.service.IDeviceWellViewService; +import com.casic.common.general.DataFrame; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.Serializable; +import java.util.List; + + +@Service +@Slf4j +public class TubeFrameServiceImpl implements ITubeFrameService { + + @Resource + private CasicProtocol tubeProtocol; + + @Resource + IDataTubeOtherService tubeDataService; + + @Resource + IDeviceWellViewService deviceService; + + public CasicFrame dataParse(String frame) { + // 1. 判断帧结构 + boolean frameValid = tubeProtocol.checkFrame(frame); + if (frameValid) { + // 2. 获取帧结构中的关键字段信息 + String deviceId = tubeProtocol.getDeviceId(frame); + String deviceType = tubeProtocol.getDeviceType(frame); + String messageType = tubeProtocol.getMessageType(frame); + String messageBody = tubeProtocol.getMessageBody(frame).toUpperCase(); + String uptime = tubeProtocol.getUptime(frame); + + String manufacturerCode = tubeProtocol.getManufacturerCode(frame); + CasicFrame tubeFrame = CasicFrameBuildFactory.buildCasicFrame(messageType, manufacturerCode, deviceType); + + if (tubeFrame != null) { + tubeFrame.setDeviceCode(deviceId); + tubeFrame.setUptime(uptime); + tubeFrame.setMessageType(messageType); + + // 心跳类的消息不解析MessageBody + if (!tubeFrame.getMessageType().equals("00")) { + tubeFrame.setMessageBody(tubeProtocol.parseMessageBody(messageBody)); + tubeFrame.parseMessageBody(); + } + + log.info("收到设备消息:{}", tubeFrame); + return tubeFrame; + } + } else { + log.error("消息帧解析异常"); + } + + return null; + } + + @Override + public String doBuildCommand(CasicFrame cmd) { + return tubeProtocol.buildFrameStr(cmd); + } + + @Override + public void afterAction(CasicFrame frame) { + // 数据消息帧 进行存库操作 + if (frame instanceof DataFrame) { + String devCode = frame.getDeviceCode(); + DeviceWellView devWellView = deviceService.getDeviceWellViewByDevCode(devCode); + String wellCode = ""; + if (devWellView != null) { + wellCode = devWellView.getWellCode(); + } + List dataList = ((DataFrame) frame).toDataModelList(); + if (dataList != null) { + for (Serializable item : dataList) { + DataTubeOther data = (DataTubeOther) item; + data.setWellCode(wellCode); + tubeDataService.save(data); + } + } + } + } +} diff --git a/pom.xml b/pom.xml index d7aa232..ea8fb2d 100644 --- a/pom.xml +++ b/pom.xml @@ -110,32 +110,83 @@ - org.springframework.boot - spring-boot-maven-plugin - 2.1.3.RELEASE + org.apache.maven.plugins + maven-jar-plugin - true - - com.casic.CasicApplication - exec - true + + + *.properties + *.yml + *.yaml + *.xml + + + + + com.casic.CasicApplication + + true + + lib/ + + false + + + + config/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + copy-dependencies + package - repackage + copy-dependencies + ${project.build.directory}/lib + + + + + + + maven-resources-plugin + + + copy-resources + package + + copy-resources + + + + + + src/main/resources/ + + *.properties + *.yml + *.yaml + *.xml + + + + ${project.build.directory}/config + org.apache.maven.plugins - maven-war-plugin - - - false - + maven-compiler-plugin + 3.1 diff --git a/src/main/java/com/casic/common/CasicFrameBuildFactory.java b/src/main/java/com/casic/common/CasicFrameBuildFactory.java index 899c992..a2a5e8e 100644 --- a/src/main/java/com/casic/common/CasicFrameBuildFactory.java +++ b/src/main/java/com/casic/common/CasicFrameBuildFactory.java @@ -1,11 +1,14 @@ package com.casic.common; -import com.casic.tube.frame.ConfigResponseFrame; -import com.casic.tube.frame.HeartFrame; +import com.casic.common.general.ConfigResponseFrame; +import com.casic.common.general.HeartFrame; +import com.casic.senitnel.frame.ncx.DataFrameNCX; +import com.casic.senitnel.frame.ncx.EventFrameNCX; +import com.casic.senitnel.frame.ncx.InfoFrameNCX; import com.casic.tube.frame.brs.DataFrameBRS; import com.casic.tube.frame.brs.EventFrameBRS; import com.casic.tube.frame.brs.InfoFrameBRS; -import com.casic.tube.frame.IMEIFrame; +import com.casic.common.general.IMEIFrame; import com.casic.tube.frame.mhk.DataFrameMHK; import com.casic.tube.frame.mhk.EventFrameMHK; import com.casic.tube.frame.mhk.InfoFrameMHK; @@ -15,16 +18,16 @@ @Slf4j public class CasicFrameBuildFactory { - public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode) { + public static CasicFrame buildCasicFrame(String messageType, String manufacturerCode, String deviceType) { switch (messageType) { case "00": return new HeartFrame(); case "01": - return buildEventFrame(manufacturerCode); + return buildEventFrame(manufacturerCode, deviceType); case "02": - return buildDataFrame(manufacturerCode); + return buildDataFrame(manufacturerCode, deviceType); case "03": return new ConfigResponseFrame(); @@ -33,7 +36,7 @@ return new IMEIFrame(); case "07": - return buildInfoFrame(manufacturerCode); + return buildInfoFrame(manufacturerCode, deviceType); default: log.warn("上行消息类型不在范围内[" + messageType + "]"); @@ -41,7 +44,46 @@ } } - private static CasicFrame buildDataFrame(String manufacturerCode) { + private static CasicFrame buildDataFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeDataFrame(manufacturerCode); + + case "21": + return buildSentinelDataFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildEventFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeEventFrame(manufacturerCode); + + case "21": + return buildSentinelEventFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildInfoFrame(String manufacturerCode, String deviceType) { + switch (deviceType) { + case "34": + return buildTubeInfoFrame(manufacturerCode); + + case "21": + return buildSentinelInfoFrame(manufacturerCode); + + default: + return null; + } + } + + private static CasicFrame buildTubeDataFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": // 百瑞生 return new DataFrameBRS(); @@ -57,7 +99,17 @@ } } - private static CasicFrame buildEventFrame(String manufacturerCode) { + private static CasicFrame buildSentinelDataFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": // 诺成新 + return new DataFrameNCX(); + + default: + return null; + } + } + + private static CasicFrame buildTubeEventFrame(String manufacturerCode) { switch (manufacturerCode) { case "15": return new EventFrameBRS(); @@ -70,14 +122,34 @@ } } - private static CasicFrame buildInfoFrame(String manufacturerCode) { + private static CasicFrame buildSentinelEventFrame(String manufacturerCode) { switch (manufacturerCode) { - case "14": - return new InfoFrameMHK(); + case "14": // 诺成新 + return new EventFrameNCX(); + default: + return null; + } + } + + private static CasicFrame buildTubeInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { case "15": return new InfoFrameBRS(); + case "16": + return new InfoFrameMHK(); + + default: + return null; + } + } + + private static CasicFrame buildSentinelInfoFrame(String manufacturerCode) { + switch (manufacturerCode) { + case "14": + return new InfoFrameNCX(); + default: return null; } diff --git a/src/main/java/com/casic/common/CasicProtocol.java b/src/main/java/com/casic/common/CasicProtocol.java index 3d59da5..68da469 100644 --- a/src/main/java/com/casic/common/CasicProtocol.java +++ b/src/main/java/com/casic/common/CasicProtocol.java @@ -14,6 +14,8 @@ String getMessageType(String frame); + String getMessageSequence(String frame); + String getMessageBody(String frame); JSONObject parseMessageBody(String messageBody); @@ -21,4 +23,6 @@ String getUptime(String frame); String buildFrameStr(CasicFrame frame); + + String buildReplyFrameStr(CasicFrame frame); } diff --git a/src/main/java/com/casic/common/general/ConfigFrame.java b/src/main/java/com/casic/common/general/ConfigFrame.java new file mode 100644 index 0000000..0113108 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigFrame.java @@ -0,0 +1,12 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigFrame extends CasicFrame { + + public ConfigFrame() { + setSequence("01"); // 默认序号 + setControl("1"); // 默认为不需要分包 + setMessageType("52"); // 消息大类 52 = SetRequest + } +} diff --git a/src/main/java/com/casic/common/general/ConfigResponseFrame.java b/src/main/java/com/casic/common/general/ConfigResponseFrame.java new file mode 100644 index 0000000..943d757 --- /dev/null +++ b/src/main/java/com/casic/common/general/ConfigResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ConfigResponseFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "03"; + final String MESSAGE_TYPE_STRING = "SetResponse"; + final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "指令序号" + getSequence() + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/DataFrame.java b/src/main/java/com/casic/common/general/DataFrame.java new file mode 100644 index 0000000..ffde717 --- /dev/null +++ b/src/main/java/com/casic/common/general/DataFrame.java @@ -0,0 +1,36 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import com.casic.dao.model.DataTubeOther; + +import java.io.Serializable; +import java.util.List; + +public class DataFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "02"; + public final String MESSAGE_TYPE_STRING = "Data"; + public final String MESSAGE_TYPE_DESCRIPTION = "数据消息"; + + public List dataItemList; + + public List toDataModelList() { + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append(";"); + builder.append("上报时间:").append(getUptime()).append(";"); + for (DataItem dataItem : dataItemList) { + builder.append("["); + builder.append(dataItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/DataItem.java b/src/main/java/com/casic/common/general/DataItem.java new file mode 100644 index 0000000..913ba8e --- /dev/null +++ b/src/main/java/com/casic/common/general/DataItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class DataItem { +} diff --git a/src/main/java/com/casic/common/general/EventFrame.java b/src/main/java/com/casic/common/general/EventFrame.java new file mode 100644 index 0000000..83a7a1d --- /dev/null +++ b/src/main/java/com/casic/common/general/EventFrame.java @@ -0,0 +1,30 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +import java.util.List; + +public class EventFrame extends CasicFrame { + + public final String MESSAGE_TYPE_IDENTIFY = "01"; + public final String MESSAGE_TYPE_STRING = "Event"; + public final String MESSAGE_TYPE_DESCRIPTION = "事件消息"; + + public List eventItemList; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + builder.append("设备编号:").append(getDeviceCode()).append("; "); + builder.append("上报时间:").append(getUptime()).append("; "); + for (EventItem eventItem : eventItemList) { + builder.append("["); + builder.append(eventItem); + builder.append("],"); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/common/general/EventItem.java b/src/main/java/com/casic/common/general/EventItem.java new file mode 100644 index 0000000..ee0dc9e --- /dev/null +++ b/src/main/java/com/casic/common/general/EventItem.java @@ -0,0 +1,4 @@ +package com.casic.common.general; + +public class EventItem { +} diff --git a/src/main/java/com/casic/common/general/HeartFrame.java b/src/main/java/com/casic/common/general/HeartFrame.java new file mode 100644 index 0000000..3be9058 --- /dev/null +++ b/src/main/java/com/casic/common/general/HeartFrame.java @@ -0,0 +1,22 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class HeartFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "00"; + final String MESSAGE_TYPE_STRING = "OnlineRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "}"; + } +} diff --git a/src/main/java/com/casic/common/general/IMEIFrame.java b/src/main/java/com/casic/common/general/IMEIFrame.java new file mode 100644 index 0000000..fb1b962 --- /dev/null +++ b/src/main/java/com/casic/common/general/IMEIFrame.java @@ -0,0 +1,33 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Data +public class IMEIFrame extends CasicFrame { + + final String MESSAGE_TYPE_IDENTIFY = "05"; + final String MESSAGE_TYPE_STRING = "StartupRequest"; + final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; + + String imei; + String iccid; + + @Override + public String toString() { + return "{" + + MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + + "设备编号:" + getDeviceCode() + ";" + + "上报时间:" + getUptime() + ";" + + "IMEI:" + imei + ";" + + "ICCID:" + iccid + + "}"; + } + + @Override + public void parseMessageBody() { + imei = getMessageBody().getString("IMEI"); + iccid = getMessageBody().getString("ICCID"); + } +} diff --git a/src/main/java/com/casic/common/general/ReplyFrame.java b/src/main/java/com/casic/common/general/ReplyFrame.java new file mode 100644 index 0000000..56d9dbb --- /dev/null +++ b/src/main/java/com/casic/common/general/ReplyFrame.java @@ -0,0 +1,11 @@ +package com.casic.common.general; + +import com.casic.common.CasicFrame; + +public class ReplyFrame extends CasicFrame { + + public ReplyFrame() { + setControl("1"); // 默认为不需要分包 + setMessageType("51"); // 消息大类 51 = GetResponse,对应OnlineRequest、StartupRequest、Info、Data、Event的回复消息 + } +} diff --git a/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java new file mode 100644 index 0000000..0ab6ed7 --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/BusDeviceMapper.java @@ -0,0 +1,19 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.BusDevice; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface BusDeviceMapper extends BaseMapper { + + BusDevice getOneByDevCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java new file mode 100644 index 0000000..f33742b --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/DataSentinelOtherMapper.java @@ -0,0 +1,18 @@ +package com.casic.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 报警数据 Mapper 接口 + *

+ * + * @author cz + * @since 2023-11-20 + */ +@Mapper +public interface DataSentinelOtherMapper extends BaseMapper { + +} diff --git a/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml new file mode 100644 index 0000000..37c0c9c --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/BusDeviceMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + ID, DEVCODE, DEVICE_NAME, DEVICE_TYPE, MASTER_API_KEY, SECRET_KEY + + + + + diff --git a/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml new file mode 100644 index 0000000..d3c647e --- /dev/null +++ b/src/main/java/com/casic/dao/mapper/mapping/DataSentinelOtherMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, DEVCODE, WELL_CODE, GASVAL, UPTIME, LOGTIME + + + + ${paramStr} + + + + TO_TIMESTAMP(${paramStr},'yyyy-MM-dd hh24:mi:ss')::timestamp without time zone + + + + TO_DATE(${paramStr},'yyyy-mm-dd hh24:mi') + + + diff --git a/src/main/java/com/casic/dao/model/BusDevice.java b/src/main/java/com/casic/dao/model/BusDevice.java new file mode 100644 index 0000000..2288afe --- /dev/null +++ b/src/main/java/com/casic/dao/model/BusDevice.java @@ -0,0 +1,60 @@ +package com.casic.dao.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 设备 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("bus_device") +public class BusDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 设备名称 + */ + @TableField("DEVICE_NAME") + private String deviceName; + + /** + * 设备类型(字典值) + */ + @TableField("DEVICE_TYPE") + private String deviceType; + + /** + * NB平台APIKEY + */ + @TableField("MASTER_API_KEY") + private String masterApiKey; + + /** + * 密钥 + */ + @TableField("SECRET_KEY") + private String secretKey; + +} diff --git a/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java new file mode 100644 index 0000000..e69087e --- /dev/null +++ b/src/main/java/com/casic/dao/model/DataMonitorPipeOther.java @@ -0,0 +1,132 @@ +package com.casic.dao.model; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 第三方厂家管盯数据 + *

+ * + * @author tanyue + * @since 2024-07-01 + */ +@Data +@TableName("data_monitor_pipe_other") +public class DataMonitorPipeOther implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编号 + */ + @TableId("ID") + private Long id; + + /** + * 设备编号 + */ + @TableField("DEVCODE") + private String devcode; + + /** + * 点位编号 + */ + @TableField("WELL_CODE") + private String wellCode; + + /** + * 左侧甲烷值 + */ + @TableField("LEFT_GAS") + private String leftGas; + + /** + * 左侧指示带长度 + */ + @TableField("LEFT_LENGTH") + private String leftLength; + + /** + * 右侧甲烷值 + */ + @TableField("RIGHT_GAS") + private String rightGas; + + /** + * 右侧指示带长度 + */ + @TableField("RIGHT_LENGTH") + private String rightLength; + + /** + * 设备电池电压值(毫伏) + */ + @TableField("VBAT") + private String vbat; + + /** + * 桩倾斜报警(1有报警输出,0无报警输出) + */ + @TableField("PIPE_INCLINE_ALARM") + private String pipeInclineAlarm; + + /** + * 桩拆卸报警 + */ + @TableField("PIPE_BREAK_ALARM") + private String pipeBreakAlarm; + + /** + * 燃气泄漏报警 + */ + @TableField("GAS_ALARM") + private String gasAlarm; + + + /** + * 左断线报警 + */ + @TableField("LEFT_OFF_LINE_ALARM") + private String leftOfflineAlarm; + + /** + * 左振动报警 + */ + @TableField("LEFT_VIBRATE_ALARM") + private String leftVibrateAlarm; + + /** + * 右线报警 + */ + @TableField("RIGHT_OFF_LINE_ALARM") + private String rightOfflineAlarm; + + /** + * 右振动报警 + */ + @TableField("RIGHT_VIBRATE_ALARM") + private String rightVibrateAlarm; + + /** + * 采集时间 + */ + @TableField("UPTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uptime; + + /** + * 上传时间 默认为当前时间 + */ + @TableField("LOGTIME") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime logtime; + + +} diff --git a/src/main/java/com/casic/dao/service/IBusDeviceService.java b/src/main/java/com/casic/dao/service/IBusDeviceService.java new file mode 100644 index 0000000..ab00942 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IBusDeviceService.java @@ -0,0 +1,9 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.BusDevice; + +public interface IBusDeviceService extends IService { + + BusDevice getDeviceByCode(String devCode); +} diff --git a/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java new file mode 100644 index 0000000..95d2bd4 --- /dev/null +++ b/src/main/java/com/casic/dao/service/IDataSentinelOtherService.java @@ -0,0 +1,8 @@ +package com.casic.dao.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.casic.dao.model.DataMonitorPipeOther; + +public interface IDataSentinelOtherService extends IService { + +} diff --git a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java index d6b1200..0290829 100644 --- a/src/main/java/com/casic/dao/service/IDeviceWellViewService.java +++ b/src/main/java/com/casic/dao/service/IDeviceWellViewService.java @@ -1,7 +1,6 @@ package com.casic.dao.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.casic.dao.model.DataTubeOther; import com.casic.dao.model.DeviceWellView; public interface IDeviceWellViewService extends IService { diff --git a/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java new file mode 100644 index 0000000..be34f77 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/BusDeviceServiceImpl.java @@ -0,0 +1,16 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.BusDeviceMapper; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import org.springframework.stereotype.Service; + +@Service +public class BusDeviceServiceImpl extends ServiceImpl implements IBusDeviceService { + + @Override + public BusDevice getDeviceByCode(String devCode) { + return baseMapper.getOneByDevCode(devCode); + } +} diff --git a/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java new file mode 100644 index 0000000..0db2007 --- /dev/null +++ b/src/main/java/com/casic/dao/service/impl/DataSentinelOtherServiceImpl.java @@ -0,0 +1,11 @@ +package com.casic.dao.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.casic.dao.mapper.DataSentinelOtherMapper; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.service.IDataSentinelOtherService; +import org.springframework.stereotype.Service; + +@Service +public class DataSentinelOtherServiceImpl extends ServiceImpl implements IDataSentinelOtherService { +} diff --git a/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java new file mode 100644 index 0000000..d8c5ef2 --- /dev/null +++ b/src/main/java/com/casic/protocol/CasicTubeProtocolImpl.java @@ -0,0 +1,111 @@ +package com.casic.protocol; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.CasicProtocol; +import org.springframework.stereotype.Component; + +@Component +public class CasicTubeProtocolImpl implements CasicProtocol { + @Override + public boolean checkFrame(String frame) { + boolean valid = checkFrameHeaderAndTail(frame); + if (valid) { + valid = checkFrameLength(frame); + } + + return valid; + } + + private boolean checkFrameHeaderAndTail(String frame) { + return (frame.substring(0, 2).equalsIgnoreCase("AA")) && + (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); + } + + private boolean checkFrameLength(String frame) { + String lengthStr = frame.substring(4, 7); + int length = Integer.parseInt(lengthStr); + + return frame.length() == length + 9; + } + + @Override + public String getDeviceType(String frame) { + return frame.substring(7, 9); + } + + @Override + public String getDeviceId(String frame) { + return frame.substring(9, 21); + } + + @Override + public String getManufacturerCode(String frame) { + return frame.substring(11, 13); + } + + @Override + public String getMessageType(String frame) { + return frame.substring(21, 23); + } + + @Override + public String getMessageSequence(String frame) { + return frame.substring(23, 25); + } + + @Override + public String getMessageBody(String frame) { + return frame.substring(26, frame.length() - 16); + } + + @Override + public JSONObject parseMessageBody(String messageBody) { + return JSONObject.parseObject(messageBody); + } + + @Override + public String getUptime(String frame) { + return frame.substring(frame.length() - 16, frame.length() - 2); + } + + @Override + public String buildFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append(frame.getMessageBody().toJSONString()); + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } + + @Override + public String buildReplyFrameStr(CasicFrame frame) { + StringBuilder builder = new StringBuilder(); + + builder.append(frame.getDeviceType()); + builder.append(frame.getDeviceCode()); + builder.append(frame.getMessageType()); + builder.append(frame.getSequence()); + builder.append(frame.getControl()); + builder.append("00"); // 消息响应类消息 消息体为00 + builder.append(frame.getUptime()); + + builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 + builder.insert(0, frame.getVersion()); + builder.insert(0, frame.getHEADER()); + builder.append(frame.getTAIL()); + + return builder.toString(); + } +} diff --git a/src/main/java/com/casic/senitnel/controller/SentinelDataController.java b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java new file mode 100644 index 0000000..633c072 --- /dev/null +++ b/src/main/java/com/casic/senitnel/controller/SentinelDataController.java @@ -0,0 +1,120 @@ +package com.casic.senitnel.controller; + +import com.alibaba.fastjson.JSONObject; +import com.casic.common.CasicFrame; +import com.casic.common.general.ConfigFrame; +import com.casic.dao.model.BusDevice; +import com.casic.dao.service.IBusDeviceService; +import com.casic.senitnel.service.ISentinelFrameService; +import com.casic.util.aep.AepCommandSend; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Base64; +import java.util.Map; + +@Slf4j +@RestController +public class SentinelDataController { + + @Resource + private ISentinelFrameService frameService; + + @Resource + private IBusDeviceService deviceService; + + @RequestMapping("/sentinel/data/recv") + public Object dataRecv(@RequestBody Map map) { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + + JSONObject recvObj = (JSONObject) JSONObject.toJSON(map); + if (recvObj.containsKey("payload")) { + JSONObject payload = recvObj.getJSONObject("payload"); + String value = payload.getString("APPdata"); + + if (value.isEmpty()) { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } else { + byte[] baseBytes = Base64.getDecoder().decode(value); + String frameStr = new String(baseBytes); + + // 根据协议进行解析 + CasicFrame frame = frameService.dataParse(frameStr); + + if (frame != null) { + // 回复响应 + String replyFrameStr = frameService.replyMessage(frame.getDeviceCode(), frame.getSequence()); + + // 从数据库中获取master-api-key 回复响应消息 + BusDevice device = deviceService.getDeviceByCode(frame.getDeviceCode()); + if (device != null && StringUtils.isNotBlank(device.getMasterApiKey())) { + String masterApiKey = device.getMasterApiKey(); + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + + try { + int code = aepCommandSend.handleAndReply(replyFrameStr); + } catch (Exception ex) { + log.error("向设备回复响应异常:{}", ex.getMessage()); + } + } + + // 存库 + frameService.afterAction(frame); + } + + retObj.put("code", 200); + retObj.put("success", true); + } + } else { + retObj.put("resp", "payload not matched"); + retObj.put("code", 200); + retObj.put("success", false); + } + + return retObj; + } + + @RequestMapping("/sentinel/config/send") + public Object configSend(@RequestBody Map map) throws Exception { + JSONObject retObj = new JSONObject(); + log.info(JSONObject.toJSONString(map)); + + CasicFrame cmdFrame = new ConfigFrame(); + cmdFrame.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + cmdFrame.setDeviceCode((String) map.get("devCode")); + cmdFrame.setSequence("01"); + cmdFrame.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + JSONObject messageBody = new JSONObject(); + messageBody.put("datas", map.get("cmdList")); + cmdFrame.setMessageBody(messageBody); + + String frameStr = frameService.doBuildCommand(cmdFrame); + + // TODO-LIST + // 这三个参数根据设备编号从数据库中取 + String deviceId = (String) map.get("deviceId"); + String productId = (String) map.get("productId"); + String masterApiKey = (String) map.get("masterApiKey"); + + AepCommandSend aepCommandSend = new AepCommandSend(deviceId, productId, masterApiKey); + int code = aepCommandSend.handleAndReply(frameStr); + + retObj.put("code", 200); + retObj.put("success", true); + retObj.put("AEPRetCode", code); + return retObj; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java new file mode 100644 index 0000000..368af03 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataFrameNCX.java @@ -0,0 +1,82 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; +import com.casic.dao.model.DataMonitorPipeOther; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class DataFrameNCX extends DataFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + dataItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + DataItemNCX dataItem = new DataItemNCX(); + + dataItem.setLenL(dataObj.getString("LENGL")); + dataItem.setLenR(dataObj.getString("LENGR")); + dataItem.setBat(dataObj.getString("BAT")); + dataItem.setCh4L(dataObj.getString("CH4L")); + dataItem.setCh4R(dataObj.getString("CH4R")); + dataItem.setSlope(dataObj.getString("SLOPING")); + dataItem.setDestroy(dataObj.getString("DESTROY")); + dataItem.setLeak(dataObj.getString("LEAK")); + dataItem.setDiscL(dataObj.getString("DISCL")); + dataItem.setDiscR(dataObj.getString("DISCR")); + dataItem.setVibL(dataObj.getString("VIBL")); + dataItem.setVibR(dataObj.getString("VIBR")); + dataItem.setTime(dataObj.getString("UPTIME")); + + dataItemList.add(dataItem); + } + } + + @Override + public List toDataModelList() { + List dataList = new ArrayList<>(); + for (DataItem dataItem : dataItemList) { + DataMonitorPipeOther data = new DataMonitorPipeOther(); + + data.setDevcode(getDeviceCode()); + data.setLeftLength(((DataItemNCX)dataItem).getLenL()); + data.setRightLength(((DataItemNCX)dataItem).getLenR()); + data.setLeftGas(((DataItemNCX)dataItem).getCh4L()); + data.setRightGas(((DataItemNCX)dataItem).getCh4R()); + data.setVbat(((DataItemNCX)dataItem).getBat()); + data.setPipeInclineAlarm(((DataItemNCX)dataItem).getSlope()); + data.setPipeBreakAlarm(((DataItemNCX)dataItem).getDestroy()); + data.setGasAlarm(((DataItemNCX)dataItem).getLeak()); + data.setLeftOfflineAlarm(((DataItemNCX)dataItem).getDiscL()); + data.setRightOfflineAlarm(((DataItemNCX)dataItem).getDiscR()); + data.setLeftVibrateAlarm(((DataItemNCX)dataItem).getVibL()); + data.setRightVibrateAlarm(((DataItemNCX)dataItem).getVibR()); + data.setUptime(LocalDateTime.parse(((DataItemNCX)dataItem).getTime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 采集时间 + data.setLogtime(LocalDateTime.parse(getUptime(), DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 上报时间 + + dataList.add(data); + } + + return dataList; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java new file mode 100644 index 0000000..372ac73 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/DataItemNCX.java @@ -0,0 +1,31 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.DataItem; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class DataItemNCX extends DataItem { + String lenL; // 左侧指示带长度 + String lenR; // 右侧指示带长度 + String ch4L; // 左侧甲烷浓度值 + String ch4R; // 右侧甲烷浓度值 + String bat; // 电池电压 + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String spare; // 备用 + String time; // 采集时间 + + @Override + public String toString() { + return "气体浓度值:" + "(" + ch4L + "," + ch4R + ")" + "%LEL;" + + "电池电压值:" + bat + "v;" + + "采样时间:" + time; + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java new file mode 100644 index 0000000..b3bbcf4 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventFrameNCX.java @@ -0,0 +1,43 @@ +package com.casic.senitnel.frame.ncx; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.common.general.EventFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class EventFrameNCX extends EventFrame { + + @Override + public String toString() { + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "燃气监测桩" + "(" + MESSAGE_TYPE_STRING + "/" + "Sentinel" + ")"; + return prefix + super.toString(); + } + + @Override + public void parseMessageBody() { + JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); + eventItemList = new ArrayList<>(); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObj = dataArray.getJSONObject(i); + EventItemNCX eventItem = new EventItemNCX(); + + eventItem.setSlope(dataObj.getString("SLOPING")); + eventItem.setDestroy(dataObj.getString("DESTROY")); + eventItem.setLeak(dataObj.getString("LEAK")); + eventItem.setDiscL(dataObj.getString("DISCL")); + eventItem.setDiscR(dataObj.getString("DISCR")); + eventItem.setVibL(dataObj.getString("VIBL")); + eventItem.setVibR(dataObj.getString("VIBR")); + eventItem.setTime(dataObj.getString("UPTIME")); + + eventItemList.add(eventItem); + } + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java new file mode 100644 index 0000000..1a560d0 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/EventItemNCX.java @@ -0,0 +1,49 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.general.EventItem; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.commons.lang3.StringUtils; + +@EqualsAndHashCode(callSuper = true) +@Data +public class EventItemNCX extends EventItem { + String slope; // 桩倾斜报警 + String destroy; // 桩破坏报警 + String leak; // 燃气泄漏报警 + String discL; // 左侧断线报警 + String discR; // 右侧断线报警 + String vibL; // 左侧震动报警 + String vibR; // 右侧震动报警 + String time; // 采集时间 + + @Override + public String toString() { + String str = ""; + if (StringUtils.isNotBlank(slope) && slope.equalsIgnoreCase("1")) { + str += "[倾斜报警]"; + } + if (StringUtils.isNotBlank(destroy) && destroy.equalsIgnoreCase("1")) { + str += "[破坏报警]"; + } + if (StringUtils.isNotBlank(leak) && leak.equalsIgnoreCase("1")) { + str += "[甲烷泄漏报警]"; + } + if (StringUtils.isNotBlank(discL) && discL.equalsIgnoreCase("1")) { + str += "[左侧断线报警]"; + } + if (StringUtils.isNotBlank(discR) && discR.equalsIgnoreCase("1")) { + str += "[右侧断线报警]"; + } + if (StringUtils.isNotBlank(vibL) && vibL.equalsIgnoreCase("1")) { + str += "[左侧振动报警]"; + } + if (StringUtils.isNotBlank(vibR) && vibR.equalsIgnoreCase("1")) { + str += "[右侧振动报警]"; + } + str += "采样时间:" + time; + + return str; + + } +} diff --git a/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java new file mode 100644 index 0000000..343c4d6 --- /dev/null +++ b/src/main/java/com/casic/senitnel/frame/ncx/InfoFrameNCX.java @@ -0,0 +1,37 @@ +package com.casic.senitnel.frame.ncx; + +import com.casic.common.CasicFrame; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; + +@EqualsAndHashCode(callSuper = true) +@Data +@Slf4j +public class InfoFrameNCX extends CasicFrame { + + String workMode; + String model; + String hwVersion; + String softVersion; + String sensorType; + + @Override + public String toString() { + return "设备编号: " + getDeviceCode() + "; " + + "设备工作模式: " + workMode + " ; " + + "设备型号: " + model + " ; " + + "版本号: " + hwVersion + ", " + softVersion + "; " + + "传感器类型: " + sensorType + " ; " + + "上报时间: " + getUptime(); + } + + @Override + public void parseMessageBody() { + workMode = getMessageBody().getString("WORKMODE"); + model = getMessageBody().getString("MODEL"); + hwVersion = getMessageBody().getString("HWVERSION"); + softVersion = getMessageBody().getString("SOFTVERSION"); + sensorType = getMessageBody().getString("SENSORTYPE"); + } +} diff --git a/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java new file mode 100644 index 0000000..e76fc86 --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/ISentinelFrameService.java @@ -0,0 +1,14 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; + +public interface ISentinelFrameService { + + CasicFrame dataParse(String frame); + + String replyMessage(String deviceCode, String sequence); + + String doBuildCommand(CasicFrame cmd); + + void afterAction(CasicFrame frame); +} diff --git a/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java new file mode 100644 index 0000000..803ff0e --- /dev/null +++ b/src/main/java/com/casic/senitnel/service/SentinelFrameServiceImpl.java @@ -0,0 +1,109 @@ +package com.casic.senitnel.service; + +import com.casic.common.CasicFrame; +import com.casic.common.CasicFrameBuildFactory; +import com.casic.common.CasicProtocol; +import com.casic.common.general.DataFrame; +import com.casic.common.general.EventFrame; +import com.casic.common.general.ReplyFrame; +import com.casic.dao.model.DataMonitorPipeOther; +import com.casic.dao.model.DeviceWellView; +import com.casic.dao.service.IDataSentinelOtherService; +import com.casic.dao.service.IDeviceWellViewService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + + +@Service +@Slf4j +public class SentinelFrameServiceImpl implements ISentinelFrameService { + + @Resource + private CasicProtocol protocol; + + @Resource + IDataSentinelOtherService sentinelDataService; + + @Resource + IDeviceWellViewService deviceService; + + public CasicFrame dataParse(String frame) { + // 1. 判断帧结构 + boolean frameValid = protocol.checkFrame(frame); + if (frameValid) { + // 2. 获取帧结构中的关键字段信息 + String deviceId = protocol.getDeviceId(frame); + String deviceType = protocol.getDeviceType(frame); + String messageType = protocol.getMessageType(frame); + String messageBody = protocol.getMessageBody(frame).toUpperCase(); + String uptime = protocol.getUptime(frame); + String sequence = protocol.getMessageSequence(frame); + + String manufacturerCode = protocol.getManufacturerCode(frame); + CasicFrame sentinelFrame = CasicFrameBuildFactory.buildCasicFrame(messageType, manufacturerCode, deviceType); + + if (sentinelFrame != null) { + sentinelFrame.setDeviceCode(deviceId); + sentinelFrame.setUptime(uptime); + sentinelFrame.setMessageType(messageType); + sentinelFrame.setSequence(sequence); + + // 心跳类的消息不解析MessageBody + if (!sentinelFrame.getMessageType().equals("00")) { + sentinelFrame.setMessageBody(protocol.parseMessageBody(messageBody)); + sentinelFrame.parseMessageBody(); + } + + log.info("收到设备消息:{}", sentinelFrame); + return sentinelFrame; + } + } else { + log.error("消息帧解析异常"); + } + + return null; + } + + @Override + public String replyMessage(String deviceCode, String sequence) { + CasicFrame reply = new ReplyFrame(); + reply.setDeviceType("21"); // 设备类型为 燃气监测桩(防第三方破坏) + reply.setDeviceCode(deviceCode); + reply.setSequence(sequence); + reply.setUptime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 当前时刻 + + return protocol.buildReplyFrameStr(reply); + } + + @Override + public String doBuildCommand(CasicFrame cmd) { + return protocol.buildFrameStr(cmd); + } + + @Override + public void afterAction(CasicFrame frame) { + // 数据消息帧 进行存库操作 + if (frame instanceof DataFrame) { + String devCode = frame.getDeviceCode(); + DeviceWellView devWellView = deviceService.getDeviceWellViewByDevCode(devCode); + String wellCode = ""; + if (devWellView != null) { + wellCode = devWellView.getWellCode(); + } + List dataList = ((DataFrame) frame).toDataModelList(); + if (dataList != null) { + for (Serializable item : dataList) { + DataMonitorPipeOther data = (DataMonitorPipeOther) item; + data.setWellCode(wellCode); + sentinelDataService.save(data); + } + } + } + } +} diff --git a/src/main/java/com/casic/tube/controller/TubeDataController.java b/src/main/java/com/casic/tube/controller/TubeDataController.java index 61486c5..4965449 100644 --- a/src/main/java/com/casic/tube/controller/TubeDataController.java +++ b/src/main/java/com/casic/tube/controller/TubeDataController.java @@ -2,8 +2,8 @@ import com.alibaba.fastjson.JSONObject; import com.casic.common.CasicFrame; -import com.casic.tube.frame.ConfigFrame; -import com.casic.tube.service.ITubeDataService; +import com.casic.common.general.ConfigFrame; +import com.casic.tube.service.ITubeFrameService; import com.casic.util.aep.AepCommandSend; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestBody; @@ -21,7 +21,7 @@ public class TubeDataController { @Resource - private ITubeDataService tubeDataService; + private ITubeFrameService frameService; @RequestMapping("/tube/data/recv") public Object dataRecv(@RequestBody Map map) { @@ -42,10 +42,10 @@ String frameStr = new String(baseBytes); // 根据协议进行解析 - CasicFrame frame = tubeDataService.dataParse(frameStr); + CasicFrame frame = frameService.dataParse(frameStr); // 存库 - tubeDataService.afterAction(frame); + frameService.afterAction(frame); retObj.put("code", 200); retObj.put("success", true); @@ -74,7 +74,7 @@ messageBody.put("datas", map.get("cmdList")); cmdFrame.setMessageBody(messageBody); - String frameStr = tubeDataService.doBuildCommand(cmdFrame); + String frameStr = frameService.doBuildCommand(cmdFrame); // TODO-LIST // 这三个参数根据设备编号从数据库中取 diff --git a/src/main/java/com/casic/tube/frame/ConfigFrame.java b/src/main/java/com/casic/tube/frame/ConfigFrame.java deleted file mode 100644 index 883dad6..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigFrame.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigFrame extends CasicFrame { - - public ConfigFrame() { - setSequence("01"); // 默认序号 - setControl("1"); // 默认为不需要分包 - setMessageType("52"); // 消息大类 52 = SetRequest - } -} diff --git a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java b/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java deleted file mode 100644 index a419145..0000000 --- a/src/main/java/com/casic/tube/frame/ConfigResponseFrame.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -public class ConfigResponseFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "03"; - final String MESSAGE_TYPE_STRING = "SetResponse"; - final String MESSAGE_TYPE_DESCRIPTION = "配置参数响应"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "指令序号" + getSequence() + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/DataFrame.java b/src/main/java/com/casic/tube/frame/DataFrame.java deleted file mode 100644 index 97e07b8..0000000 --- a/src/main/java/com/casic/tube/frame/DataFrame.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import com.casic.dao.model.DataTubeOther; - -import java.util.List; - -public class DataFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "02"; - final String MESSAGE_TYPE_STRING = "Data/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "数据消息/管盯"; - - public List dataItemList; - - public List toDataModelList() { - return null; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append(";"); - builder.append("上报时间:").append(getUptime()).append(";"); - for (DataItem dataItem : dataItemList) { - builder.append("["); - builder.append(dataItem); - builder.append("],"); - } - builder.deleteCharAt(builder.length() - 1); - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/DataItem.java b/src/main/java/com/casic/tube/frame/DataItem.java deleted file mode 100644 index 4e9aceb..0000000 --- a/src/main/java/com/casic/tube/frame/DataItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class DataItem { -} diff --git a/src/main/java/com/casic/tube/frame/EventFrame.java b/src/main/java/com/casic/tube/frame/EventFrame.java deleted file mode 100644 index ea800b4..0000000 --- a/src/main/java/com/casic/tube/frame/EventFrame.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; - -import java.util.List; - -public class EventFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "01"; - final String MESSAGE_TYPE_STRING = "Event/Tube"; - final String MESSAGE_TYPE_DESCRIPTION = "事件消息/管盯"; - - public List eventItemList; - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - builder.append(MESSAGE_TYPE_DESCRIPTION).append(":").append(MESSAGE_TYPE_STRING).append(";"); - builder.append("设备编号:").append(getDeviceCode()).append("; "); - builder.append("上报时间:").append(getUptime()).append("; "); - for (EventItem eventItem : eventItemList) { - builder.append("["); - builder.append(eventItem); - builder.append("],"); - } - builder.append("}"); - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/frame/EventItem.java b/src/main/java/com/casic/tube/frame/EventItem.java deleted file mode 100644 index a1245bf..0000000 --- a/src/main/java/com/casic/tube/frame/EventItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.casic.tube.frame; - -public class EventItem { -} diff --git a/src/main/java/com/casic/tube/frame/HeartFrame.java b/src/main/java/com/casic/tube/frame/HeartFrame.java deleted file mode 100644 index af7e7a6..0000000 --- a/src/main/java/com/casic/tube/frame/HeartFrame.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; - -@Data -public class HeartFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "00"; - final String MESSAGE_TYPE_STRING = "OnlineRequest"; - final String MESSAGE_TYPE_DESCRIPTION = "心跳消息"; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "}"; - } -} diff --git a/src/main/java/com/casic/tube/frame/IMEIFrame.java b/src/main/java/com/casic/tube/frame/IMEIFrame.java deleted file mode 100644 index 9420620..0000000 --- a/src/main/java/com/casic/tube/frame/IMEIFrame.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.casic.tube.frame; - -import com.casic.common.CasicFrame; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; - -@Data -public class IMEIFrame extends CasicFrame { - - final String MESSAGE_TYPE_IDENTIFY = "05"; - final String MESSAGE_TYPE_STRING = "StartupRequest"; - final String MESSAGE_TYPE_DESCRIPTION = "开机上报消息"; - - String imei; - String iccid; - - @Override - public String toString() { - return "{" + - MESSAGE_TYPE_DESCRIPTION + ":" + MESSAGE_TYPE_STRING + ";" + - "设备编号:" + getDeviceCode() + ";" + - "上报时间:" + getUptime() + ";" + - "IMEI:" + imei + ";" + - "ICCID:" + iccid + - "}"; - } - - @Override - public void parseMessageBody() { - imei = getMessageBody().getString("IMEI"); - iccid = getMessageBody().getString("ICCID"); - } -} diff --git a/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java b/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java index 50e8a2b..47bf4d6 100644 --- a/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/DataFrameBRS.java @@ -3,11 +3,12 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.casic.dao.model.DataTubeOther; -import com.casic.tube.frame.DataFrame; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -19,7 +20,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override @@ -43,8 +45,8 @@ } @Override - public List toDataModelList() { - List dataList = new ArrayList<>(); + public List toDataModelList() { + List dataList = new ArrayList<>(); for (DataItem dataItem : dataItemList) { DataTubeOther data = new DataTubeOther(); diff --git a/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java b/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java index 8d09b10..75e94c7 100644 --- a/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/DataItemBRS.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.brs; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java b/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java index 9026b4c..2e5c145 100644 --- a/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/EventFrameBRS.java @@ -2,14 +2,11 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.casic.common.CasicFrame; -import com.casic.tube.frame.EventFrame; -import com.casic.tube.frame.EventItem; +import com.casic.common.general.EventFrame; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; -import java.util.List; @Data @Slf4j @@ -17,7 +14,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override diff --git a/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java b/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java index 6c8146c..1792320 100644 --- a/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java +++ b/src/main/java/com/casic/tube/frame/brs/EventItemBRS.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.brs; -import com.casic.tube.frame.EventItem; +import com.casic.common.general.EventItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java b/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java index e6e541c..b05b358 100644 --- a/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/DataFrameMHK.java @@ -3,11 +3,12 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.casic.dao.model.DataTubeOther; -import com.casic.tube.frame.DataFrame; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -19,7 +20,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override @@ -43,8 +45,8 @@ } @Override - public List toDataModelList() { - List dataList = new ArrayList<>(); + public List toDataModelList() { + List dataList = new ArrayList<>(); for (DataItem dataItem : dataItemList) { DataTubeOther data = new DataTubeOther(); diff --git a/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java b/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java index 0aa9bab..e875f2a 100644 --- a/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/DataItemMHK.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.mhk; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java b/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java index 9aea120..ec2d005 100644 --- a/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/EventFrameMHK.java @@ -2,13 +2,11 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.casic.common.CasicFrame; -import com.casic.tube.frame.EventFrame; +import com.casic.common.general.EventFrame; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; -import java.util.List; @Data @Slf4j @@ -16,7 +14,8 @@ @Override public String toString() { - return super.toString(); + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); } @Override diff --git a/src/main/java/com/casic/tube/frame/mhk/EventItemMHK.java b/src/main/java/com/casic/tube/frame/mhk/EventItemMHK.java index 8f6a536..e5ffed6 100644 --- a/src/main/java/com/casic/tube/frame/mhk/EventItemMHK.java +++ b/src/main/java/com/casic/tube/frame/mhk/EventItemMHK.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.mhk; -import com.casic.tube.frame.EventItem; +import com.casic.common.general.EventItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/frame/tp/DataFrameHTTP.java b/src/main/java/com/casic/tube/frame/tp/DataFrameHTTP.java index 23df423..69b7c1f 100644 --- a/src/main/java/com/casic/tube/frame/tp/DataFrameHTTP.java +++ b/src/main/java/com/casic/tube/frame/tp/DataFrameHTTP.java @@ -3,11 +3,12 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.casic.dao.model.DataTubeOther; -import com.casic.tube.frame.DataFrame; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataFrame; +import com.casic.common.general.DataItem; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -18,6 +19,12 @@ public class DataFrameHTTP extends DataFrame { @Override + public String toString(){ + String prefix = MESSAGE_TYPE_DESCRIPTION + "/" + "管盯" + "(" + MESSAGE_TYPE_STRING + "/" + "Tube" + ")"; + return prefix + super.toString(); + } + + @Override public void parseMessageBody() { JSONArray dataArray = getMessageBody().getJSONArray("DATAS"); dataItemList = new ArrayList<>(); @@ -40,8 +47,8 @@ } @Override - public List toDataModelList() { - List dataList = new ArrayList<>(); + public List toDataModelList() { + List dataList = new ArrayList<>(); for (DataItem dataItem : dataItemList) { DataTubeOther data = new DataTubeOther(); diff --git a/src/main/java/com/casic/tube/frame/tp/DataItemHTTP.java b/src/main/java/com/casic/tube/frame/tp/DataItemHTTP.java index e5281eb..49d7c87 100644 --- a/src/main/java/com/casic/tube/frame/tp/DataItemHTTP.java +++ b/src/main/java/com/casic/tube/frame/tp/DataItemHTTP.java @@ -1,6 +1,6 @@ package com.casic.tube.frame.tp; -import com.casic.tube.frame.DataItem; +import com.casic.common.general.DataItem; import lombok.Data; @Data diff --git a/src/main/java/com/casic/tube/protocol/CasicTubeProtocolImpl.java b/src/main/java/com/casic/tube/protocol/CasicTubeProtocolImpl.java deleted file mode 100644 index 4fdd78c..0000000 --- a/src/main/java/com/casic/tube/protocol/CasicTubeProtocolImpl.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.casic.tube.protocol; - -import com.alibaba.fastjson.JSONObject; -import com.casic.common.CasicFrame; -import com.casic.common.CasicProtocol; -import org.springframework.stereotype.Component; - -@Component -public class CasicTubeProtocolImpl implements CasicProtocol { - @Override - public boolean checkFrame(String frame) { - boolean valid = checkFrameHeaderAndTail(frame); - if (valid) { - valid = checkFrameLength(frame); - } - - return valid; - } - - private boolean checkFrameHeaderAndTail(String frame) { - return (frame.substring(0, 2).equalsIgnoreCase("AA")) && - (frame.substring(frame.length() - 2).equalsIgnoreCase("FF")); - } - - private boolean checkFrameLength(String frame) { - String lengthStr = frame.substring(4, 7); - int length = Integer.parseInt(lengthStr); - - return frame.length() == length + 9; - } - - @Override - public String getDeviceType(String frame) { - return frame.substring(7, 9); - } - - @Override - public String getDeviceId(String frame) { - return frame.substring(9, 21); - } - - @Override - public String getManufacturerCode(String frame) { - return frame.substring(11, 13); - } - - @Override - public String getMessageType(String frame) { - return frame.substring(21, 23); - } - - @Override - public String getMessageBody(String frame) { - return frame.substring(26, frame.length() - 16); - } - - @Override - public JSONObject parseMessageBody(String messageBody) { - return JSONObject.parseObject(messageBody); - } - - @Override - public String getUptime(String frame) { - return frame.substring(frame.length() - 16, frame.length() - 2); - } - - @Override - public String buildFrameStr(CasicFrame frame) { - StringBuilder builder = new StringBuilder(); - - builder.append(frame.getDeviceType()); - builder.append(frame.getDeviceCode()); - builder.append(frame.getMessageType()); - builder.append(frame.getSequence()); - builder.append(frame.getControl()); - builder.append(frame.getMessageBody().toJSONString()); - builder.append(frame.getUptime()); - - builder.insert(0, String.format("%03d", builder.length())); // 长度为3位数 - builder.insert(0, frame.getVersion()); - builder.insert(0, frame.getHEADER()); - builder.append(frame.getTAIL()); - - return builder.toString(); - } -} diff --git a/src/main/java/com/casic/tube/service/ITubeDataService.java b/src/main/java/com/casic/tube/service/ITubeDataService.java deleted file mode 100644 index c9dafea..0000000 --- a/src/main/java/com/casic/tube/service/ITubeDataService.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.casic.tube.service; - -import com.alibaba.fastjson.JSONObject; -import com.casic.common.CasicFrame; - -public interface ITubeDataService { - - CasicFrame dataParse(String frame); - - String doBuildCommand(CasicFrame cmd); - - void afterAction(CasicFrame frame); -} diff --git a/src/main/java/com/casic/tube/service/ITubeFrameService.java b/src/main/java/com/casic/tube/service/ITubeFrameService.java new file mode 100644 index 0000000..1ba209c --- /dev/null +++ b/src/main/java/com/casic/tube/service/ITubeFrameService.java @@ -0,0 +1,12 @@ +package com.casic.tube.service; + +import com.casic.common.CasicFrame; + +public interface ITubeFrameService { + + CasicFrame dataParse(String frame); + + String doBuildCommand(CasicFrame cmd); + + void afterAction(CasicFrame frame); +} diff --git a/src/main/java/com/casic/tube/service/TubeDataServiceImpl.java b/src/main/java/com/casic/tube/service/TubeDataServiceImpl.java deleted file mode 100644 index 46d049d..0000000 --- a/src/main/java/com/casic/tube/service/TubeDataServiceImpl.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.casic.tube.service; - -import com.casic.common.CasicFrame; -import com.casic.common.CasicFrameBuildFactory; -import com.casic.common.CasicProtocol; -import com.casic.dao.model.DataTubeOther; -import com.casic.dao.model.DeviceWellView; -import com.casic.dao.service.IDataTubeOtherService; -import com.casic.dao.service.IDeviceWellViewService; -import com.casic.tube.frame.DataFrame; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -import javax.annotation.Resource; -import java.util.List; - - -@Service -@Slf4j -public class TubeDataServiceImpl implements ITubeDataService { - - @Resource - private CasicProtocol tubeProtocol; - - @Resource - IDataTubeOtherService tubeDataService; - - @Resource - IDeviceWellViewService deviceService; - - public CasicFrame dataParse(String frame) { - // 1. 判断帧结构 - boolean frameValid = tubeProtocol.checkFrame(frame); - if (frameValid) { - // 2. 获取帧结构中的关键字段信息 - String deviceId = tubeProtocol.getDeviceId(frame); - String messageType = tubeProtocol.getMessageType(frame); - String messageBody = tubeProtocol.getMessageBody(frame).toUpperCase(); - String uptime = tubeProtocol.getUptime(frame); - - String manufacturerCode = tubeProtocol.getManufacturerCode(frame); - CasicFrame tubeFrame = CasicFrameBuildFactory.buildCasicFrame(messageType, manufacturerCode); - - if (tubeFrame != null) { - tubeFrame.setDeviceCode(deviceId); - tubeFrame.setUptime(uptime); - tubeFrame.setMessageType(messageType); - - // 心跳类的消息不解析MessageBody - if (!tubeFrame.getMessageType().equals("00")) { - tubeFrame.setMessageBody(tubeProtocol.parseMessageBody(messageBody)); - tubeFrame.parseMessageBody(); - } - - log.info("收到设备消息:{}", tubeFrame); - return tubeFrame; - } - } else { - log.error("消息帧解析异常"); - } - - return null; - } - - @Override - public String doBuildCommand(CasicFrame cmd) { - return tubeProtocol.buildFrameStr(cmd); - } - - @Override - public void afterAction(CasicFrame frame) { - // 数据消息帧 进行存库操作 - if (frame instanceof DataFrame) { - String devCode = frame.getDeviceCode(); - DeviceWellView devWellView = deviceService.getDeviceWellViewByDevCode(devCode); - String wellCode = ""; - if (devWellView != null) { - wellCode = devWellView.getWellCode(); - } - List dataList = ((DataFrame) frame).toDataModelList(); - if (dataList != null) { - for (DataTubeOther data : dataList) { - data.setWellCode(wellCode); - tubeDataService.save(data); - } - } - } - } -} diff --git a/src/main/java/com/casic/tube/service/TubeFrameServiceImpl.java b/src/main/java/com/casic/tube/service/TubeFrameServiceImpl.java new file mode 100644 index 0000000..5eaa12b --- /dev/null +++ b/src/main/java/com/casic/tube/service/TubeFrameServiceImpl.java @@ -0,0 +1,92 @@ +package com.casic.tube.service; + +import com.casic.common.CasicFrame; +import com.casic.common.CasicFrameBuildFactory; +import com.casic.common.CasicProtocol; +import com.casic.dao.model.DataTubeOther; +import com.casic.dao.model.DeviceWellView; +import com.casic.dao.service.IDataTubeOtherService; +import com.casic.dao.service.IDeviceWellViewService; +import com.casic.common.general.DataFrame; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.Serializable; +import java.util.List; + + +@Service +@Slf4j +public class TubeFrameServiceImpl implements ITubeFrameService { + + @Resource + private CasicProtocol tubeProtocol; + + @Resource + IDataTubeOtherService tubeDataService; + + @Resource + IDeviceWellViewService deviceService; + + public CasicFrame dataParse(String frame) { + // 1. 判断帧结构 + boolean frameValid = tubeProtocol.checkFrame(frame); + if (frameValid) { + // 2. 获取帧结构中的关键字段信息 + String deviceId = tubeProtocol.getDeviceId(frame); + String deviceType = tubeProtocol.getDeviceType(frame); + String messageType = tubeProtocol.getMessageType(frame); + String messageBody = tubeProtocol.getMessageBody(frame).toUpperCase(); + String uptime = tubeProtocol.getUptime(frame); + + String manufacturerCode = tubeProtocol.getManufacturerCode(frame); + CasicFrame tubeFrame = CasicFrameBuildFactory.buildCasicFrame(messageType, manufacturerCode, deviceType); + + if (tubeFrame != null) { + tubeFrame.setDeviceCode(deviceId); + tubeFrame.setUptime(uptime); + tubeFrame.setMessageType(messageType); + + // 心跳类的消息不解析MessageBody + if (!tubeFrame.getMessageType().equals("00")) { + tubeFrame.setMessageBody(tubeProtocol.parseMessageBody(messageBody)); + tubeFrame.parseMessageBody(); + } + + log.info("收到设备消息:{}", tubeFrame); + return tubeFrame; + } + } else { + log.error("消息帧解析异常"); + } + + return null; + } + + @Override + public String doBuildCommand(CasicFrame cmd) { + return tubeProtocol.buildFrameStr(cmd); + } + + @Override + public void afterAction(CasicFrame frame) { + // 数据消息帧 进行存库操作 + if (frame instanceof DataFrame) { + String devCode = frame.getDeviceCode(); + DeviceWellView devWellView = deviceService.getDeviceWellViewByDevCode(devCode); + String wellCode = ""; + if (devWellView != null) { + wellCode = devWellView.getWellCode(); + } + List dataList = ((DataFrame) frame).toDataModelList(); + if (dataList != null) { + for (Serializable item : dataList) { + DataTubeOther data = (DataTubeOther) item; + data.setWellCode(wellCode); + tubeDataService.save(data); + } + } + } + } +} diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 9d9f8a7..3f2ad30 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -13,8 +13,9 @@ pub-sub-domain: true logging: - level.root: info - level.com.casic: info + level: + root: info + com.casic: info file: path: logs/ name: missiles.log \ No newline at end of file