diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..dbaec0f
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,89 @@
+
+
+ 4.0.0
+ cc.cjyx.sc
+ zbgym
+ 0.0.1-SNAPSHOT
+ zbgym
+ 总部感应门项目
+
+ 1.8
+ UTF-8
+ UTF-8
+ 2.6.13
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+ com.alibaba
+ fastjson
+ 1.2.72
+
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+
+ org.apache.commons
+ commons-lang3
+
+
+
+ cn.snowheart
+ spring-boot-dingtalk-robot-starter
+ 1.0.2.RELEASE
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ ${spring-boot.version}
+ pom
+ import
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.1
+
+
+ 1.8
+ UTF-8
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot.version}
+
+
+
+ repackage
+
+
+
+
+
+
+
diff --git a/src/main/java/cc/cjyx/sc/Application.java b/src/main/java/cc/cjyx/sc/Application.java
new file mode 100644
index 0000000..473d839
--- /dev/null
+++ b/src/main/java/cc/cjyx/sc/Application.java
@@ -0,0 +1,14 @@
+package cc.cjyx.sc;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+
+@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
+public class Application {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+
+}
diff --git a/src/main/java/cc/cjyx/sc/common/SerialNumber.java b/src/main/java/cc/cjyx/sc/common/SerialNumber.java
new file mode 100644
index 0000000..466b3df
--- /dev/null
+++ b/src/main/java/cc/cjyx/sc/common/SerialNumber.java
@@ -0,0 +1,22 @@
+package cc.cjyx.sc.common;
+
+import java.text.SimpleDateFormat;
+
+public class SerialNumber {
+ private static final SimpleDateFormat YEAR_MONTH_FORMAT = new SimpleDateFormat("yyyyMM");
+ private static int currentSerial = 0;
+ private static String currentYearMonth;
+
+ public static synchronized String generateSerialNumber() {
+ String currentYearMonth = YEAR_MONTH_FORMAT.format(new java.util.Date());
+ if (!currentYearMonth.equals(SerialNumber.currentYearMonth)) {
+ // 当年月变化时,重置流水号
+ SerialNumber.currentYearMonth = currentYearMonth;
+ currentSerial = 1;
+ } else {
+ // 年月未变,递增流水号
+ currentSerial++;
+ }
+ return currentYearMonth + String.format("%04d", currentSerial);
+ }
+}
diff --git a/src/main/java/cc/cjyx/sc/common/TcpRunner.java b/src/main/java/cc/cjyx/sc/common/TcpRunner.java
new file mode 100644
index 0000000..46e97d0
--- /dev/null
+++ b/src/main/java/cc/cjyx/sc/common/TcpRunner.java
@@ -0,0 +1,170 @@
+package cc.cjyx.sc.common;
+
+
+import cc.cjyx.sc.utils.DataParserUtil;
+import cn.snowheart.dingtalk.robot.starter.client.DingTalkRobotClient;
+import cn.snowheart.dingtalk.robot.starter.entity.DingTalkResponse;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PreDestroy;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+
+
+@Component
+@Slf4j
+@EnableScheduling
+public class TcpRunner implements ApplicationRunner {
+
+ private Socket socket;
+
+ private OutputStream outputStream;
+
+ private InputStream inputStream;
+
+ @Value("${mobiles:15067827668,13375872885}")
+ private String mobiles;
+
+ @Autowired
+ @Qualifier("dingTalkRobotClient")
+ private DingTalkRobotClient dingTalkClient;
+
+ @Override
+ public void run(ApplicationArguments args) {
+ System.out.println("Tcp连接初始化中...");
+// System.out.println(Arrays.toString(mobiles.split(",")));
+ // 在应用程序启动后执行的代码
+ this.connect();
+ }
+
+ // 连接数据
+ private boolean connect() {
+ // 在应用程序启动后执行的代码
+ try {
+// this.socket = new Socket("cjdq.chko.cn", 9999);
+ this.socket = new Socket("192.168.100.2", 81);
+ log.info("socket connect status: {}", this.socket.isConnected());
+ return true;
+ } catch (IOException e) {
+ log.error("Tcp Client连接失败,请检查网络!", e);
+ return false;
+ }
+ }
+
+
+ @Scheduled(fixedDelay = 2000)
+ public void send() {
+ log.info("2s定时发送指令...");
+ try {
+ if (socket == null) {
+ log.info("Tcp Client未成功连接!");
+ return;
+ }
+ this.handle();
+ } catch (IOException e) {
+ log.error("Tcp Client 连接异常!", e);
+ // 尝试重新连接
+ try {
+ if(this.connect()) {
+ this.handle();
+ }
+ } catch (Exception exception) {
+ log.error("Tcp Client 重连异常!", e);
+ throw new RuntimeException(e);
+ }
+ } catch (Exception e) {
+ log.error("Tcp Client 数据请求异常!", e);
+ throw new RuntimeException(e);
+ }
+ }
+
+
+ private void handle() throws IOException {
+ // 获取写入流,用于发送数据
+ outputStream = socket.getOutputStream();
+ // 获取输入流,用于接收服务器的响应
+ inputStream = socket.getInputStream();
+
+ // 发送指令(16进制格式)
+ String hexCommand = "01 02 00 00 00 01 B9 CA";
+ byte[] command = DataParserUtil.hexString2byteArray(hexCommand);
+ outputStream.write(command);
+ outputStream.flush();
+
+ byte[] buffer = new byte[1024];
+ int length = inputStream.read(buffer);
+
+ // 解析服务器的响应(16进制格式)
+ if (length > 0) {
+ byte[] bytes = Arrays.copyOfRange(buffer, 0, length);
+// System.out.println(Arrays.toString(response));
+ String res = DataParserUtil.byteArray2HexString(bytes);
+ log.info("GET Tcp Server Response: {} ", res);
+// System.out.println("服务器响应:" + hexResponse);
+ if (bytes.length == 6) {
+ this.alarmToDingTalk(bytes[3]);
+ }
+ }
+ }
+
+ // 发送报警业务
+ private void alarmToDingTalk(Byte b) {
+// String s = DataParserUtil.formatBinary(b); // 此处在多个信号端点时,启用
+// System.out.println("bit string:" + s);
+ String[] atMobiles = mobiles.split(",");
+ if(b.intValue() == 1) {
+ String message = "("+SerialNumber.generateSerialNumber()+")"+"铜排车间安检门报警通知:当前时间(%s),感应到携带违禁物品出入,请尽快查验!";
+ LocalDateTime currentDateTime = LocalDateTime.now();
+ String time = currentDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+ message = String.format(message, time);
+ DingTalkResponse response = dingTalkClient.sendTextMessage(message, atMobiles);
+ log.info(response.toString());
+ }
+ }
+
+
+ @PreDestroy
+ public void stop() {
+ System.out.println("Tcp Client 断开连接...");
+ try {
+ if (socket != null) {
+ socket.close();
+ }
+ if (inputStream != null) {
+ inputStream.close();
+ }
+ if (outputStream != null) {
+ outputStream.close();
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+
+ public static void main(String[] args) {
+ LocalDateTime currentDateTime = LocalDateTime.now();
+// System.out.println(currentDateTime);
+// System.out.println(new Date());
+ String time = currentDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+ String message = "报警通知:当前时间(%s),感应到携带违禁物品进入,请尽快查验!";
+ message = String.format(message, time);
+ System.out.println(message);
+ }
+}
diff --git a/src/main/java/cc/cjyx/sc/test/TCPSocket.java b/src/main/java/cc/cjyx/sc/test/TCPSocket.java
new file mode 100644
index 0000000..e6a32a7
--- /dev/null
+++ b/src/main/java/cc/cjyx/sc/test/TCPSocket.java
@@ -0,0 +1,155 @@
+package cc.cjyx.sc.test;
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.net.Socket;
+import java.util.Arrays;
+import java.util.Timer;
+import java.util.TimerTask;
+
+public class TCPSocket {
+ public static void main(String args[]){
+ send();
+ }
+
+
+ public static void send() {
+ try {
+ // 创建Socket对象,指定服务器的IP地址和端口号
+ Socket socket = new Socket("cjdq.chko.cn", 9999);
+
+ // 获取输出流,用于向服务器发送指令
+ OutputStream outputStream = socket.getOutputStream();
+
+ // 创建定时器,每秒发送一次指令
+ Timer timer = new Timer();
+ timer.schedule(new TimerTask() {
+ @Override
+ public void run() {
+ try {
+ // 发送指令(16进制格式)
+ String hexCommand = "0123456789ABCDEF";
+ byte[] command = hexStrToBinaryStr(hexCommand);
+ outputStream.write(command);
+ outputStream.flush();
+
+ // 获取输入流,用于接收服务器的响应
+ InputStream inputStream = socket.getInputStream();
+ byte[] buffer = new byte[1024];
+ int length = inputStream.read(buffer);
+
+ // 解析服务器的响应(16进制格式)
+ if (length > 0) {
+ byte[] response = Arrays.copyOfRange(buffer, 0, length);
+ String hexResponse = BinaryToHexString(response);
+ System.out.println("服务器响应:" + hexResponse);
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }, 0, 1000); // 每秒发送一次
+
+ // 等待定时器结束
+ Thread.sleep(10000);
+
+ // 关闭连接和定时器
+ timer.cancel();
+ outputStream.close();
+ socket.close();
+ } catch (IOException | InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+
+ public static void send2(){
+ try {
+ //要连接的服务端IP地址
+ String host = "cjdq.chko.cn";
+ //要连接的服务端对应的监听端口
+ int port = 9999;
+ //1.建立客户端socket连接,指定服务器位置及端口
+ Socket clientSocket =new Socket(host,port);
+ //2.得到socket读写流
+ OutputStream os = clientSocket.getOutputStream();
+ // 获取输入流,用于接收服务器的响应
+ InputStream inputStream = clientSocket.getInputStream();
+
+ Thread thread = new Thread(() -> {
+ try {
+
+ while (true) {
+ // 发送指令(16进制格式)
+ String hexCommand = "01 02 00 00 00 01 B9 CA";
+ byte[] command = hexStrToBinaryStr(hexCommand);
+ os.write(command);
+ os.flush();
+
+ byte[] buffer = new byte[1024];
+ int length = inputStream.read(buffer);
+
+ // 解析服务器的响应(16进制格式)
+ if (length > 0) {
+ byte[] response = Arrays.copyOfRange(buffer, 0, length);
+ String hexResponse = BinaryToHexString(response);
+ System.out.println("服务器响应:" + hexResponse);
+ }
+
+ Thread.sleep(1000);
+ }
+ } catch (IOException | InterruptedException e) {
+ e.printStackTrace();
+ System.out.println("发生了请求异常");
+ }
+ });
+ thread.start();
+ }catch (Exception e){
+// if(clientSocket != null) {
+// clientSocket.close();
+// }
+ e.printStackTrace();
+ }
+ }
+ /**
+ * 将十六进制的字符串转换成字节数组
+ *
+ * @param hexString
+ * @return
+ */
+ public static byte[] hexStrToBinaryStr(String hexString) {
+ if (StringUtils.isEmpty(hexString)) {
+ return null;
+ }
+ hexString = hexString.replaceAll(" ", "");
+ int len = hexString.length();
+ int index = 0;
+ byte[] bytes = new byte[len / 2];
+ while (index < len) {
+ String sub = hexString.substring(index, index + 2);
+ bytes[index/2] = (byte)Integer.parseInt(sub,16);
+ index += 2;
+ }
+ return bytes;
+ }
+ /**
+ * 将字节数组转换成十六进制的字符串
+ *
+ * @return
+ */
+ public static String BinaryToHexString(byte[] bytes) {
+ String hexStr = "0123456789ABCDEF";
+ String result = "";
+ String hex = "";
+ for (byte b : bytes) {
+ hex = String.valueOf(hexStr.charAt((b & 0xF0) >> 4));
+ hex += String.valueOf(hexStr.charAt(b & 0x0F));
+ result += hex + " ";
+ }
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/cc/cjyx/sc/test/TcpServer.java b/src/main/java/cc/cjyx/sc/test/TcpServer.java
new file mode 100644
index 0000000..1ea641a
--- /dev/null
+++ b/src/main/java/cc/cjyx/sc/test/TcpServer.java
@@ -0,0 +1,40 @@
+package cc.cjyx.sc.test;
+
+import java.io.*;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+public class TcpServer {
+ public static void main(String[] args) {
+ try {
+ // 创建ServerSocket对象,指定监听的端口号
+ ServerSocket serverSocket = new ServerSocket(9991);
+
+ System.out.println("服务器启动,等待客户端连接...");
+
+ // 监听客户端连接
+ Socket socket = serverSocket.accept();
+ System.out.println("客户端连接成功!");
+
+ // 获取输入流,用于接收客户端发送的数据
+ InputStream inputStream = socket.getInputStream();
+ BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
+ String request = bufferedReader.readLine();
+ System.out.println("客户端发送的数据:" + request);
+
+ // 获取输出流,用于向客户端发送数据
+ OutputStream outputStream = socket.getOutputStream();
+ PrintWriter printWriter = new PrintWriter(outputStream);
+ printWriter.write("Hello Client!");
+ printWriter.flush();
+
+ // 关闭连接
+ printWriter.close();
+ bufferedReader.close();
+ socket.close();
+ serverSocket.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/src/main/java/cc/cjyx/sc/utils/DataParserUtil.java b/src/main/java/cc/cjyx/sc/utils/DataParserUtil.java
new file mode 100644
index 0000000..45a2960
--- /dev/null
+++ b/src/main/java/cc/cjyx/sc/utils/DataParserUtil.java
@@ -0,0 +1,104 @@
+package cc.cjyx.sc.utils;
+
+import lombok.extern.slf4j.Slf4j;
+
+// 数据解析
+@Slf4j
+public class DataParserUtil {
+
+
+ /*
+ * byte 转 bit位
+ * @description: 字节转比特
+ * 1Byte=8bits
+ */
+ public static String formatBinary(byte b) {
+ StringBuilder sb = new StringBuilder();
+ for(int i = 7; i >=0; i--) {
+ sb.append((byte) ((b >> i) & 0x1));
+ }
+ // 小端模式(低字节在前、高字节在后)
+ return sb.reverse().toString();
+ }
+
+
+
+ /**
+ * 字节数组转16进制字符串
+ *
+ * @param b 字节数组
+ * @return 16进制字符串
+ */
+ public static String byteArray2HexString(byte[] b)
+ {
+ StringBuilder sbf = new StringBuilder();
+ for (byte value : b)
+ {
+ String hex = Integer.toHexString(value & 0xFF);
+ if (hex.length() == 1)
+ {
+ hex = '0' + hex;
+ }
+ sbf.append(hex.toUpperCase()).append(" ");
+ }
+ return sbf.toString().trim();
+ }
+
+ /**
+ * 16进制字符串转字节数组
+ *
+ * @param hex 16进制字符串
+ * @return 字节数组
+ */
+ public static byte[] hexString2byteArray(String hex)
+ {
+ hex = hex.replace(" ", "");
+ if (!isHexString(hex))
+ {
+ return null;
+ }
+ char[] arr = hex.toCharArray();
+ byte[] b = new byte[hex.length() / 2];
+ for (int i = 0, j = 0, l = hex.length(); i < l; i++, j++)
+ {
+ String swap = "" + arr[i++] + arr[i];
+ int byteint = Integer.parseInt(swap, 16) & 0xFF;
+ b[j] = new Integer(byteint).byteValue();
+ }
+ return b;
+ }
+
+ /**
+ * 校验是否是16进制字符串
+ *
+ * @param hex
+ * @return boolean
+ */
+ public static boolean isHexString(String hex)
+ {
+ if (hex == null || hex.length() % 2 != 0)
+ {
+ return false;
+ }
+ for (int i = 0; i < hex.length(); i++)
+ {
+ char c = hex.charAt(i);
+ if (!isHexChar(c))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * 校验是否是16进制字符
+ *
+ * @param c
+ * @return boolean
+ */
+ private static boolean isHexChar(char c)
+ {
+ return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
+ }
+}
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
new file mode 100644
index 0000000..8fd706c
--- /dev/null
+++ b/src/main/resources/application.yml
@@ -0,0 +1,10 @@
+server:
+ port: 8881
+
+mobiles:
+ '15067827668,13375872885,13587753850'
+
+# 钉钉通知
+dingtalk:
+ robot:
+ webhook: https://oapi.dingtalk.com/robot/send?access_token=3e5c999e5a1163d7d9251c4f5781ccd1d10430c8987be3f3d377e6fea16a4293
diff --git a/src/main/resources/static/index.html b/src/main/resources/static/index.html
new file mode 100644
index 0000000..89bb8ba
--- /dev/null
+++ b/src/main/resources/static/index.html
@@ -0,0 +1,6 @@
+
+
+hello word!!!
+this is a html page
+
+
\ No newline at end of file
diff --git a/src/test/java/cc/cjyx/sc/demo/ModbusDemoApplicationTests.java b/src/test/java/cc/cjyx/sc/demo/ModbusDemoApplicationTests.java
new file mode 100644
index 0000000..c567164
--- /dev/null
+++ b/src/test/java/cc/cjyx/sc/demo/ModbusDemoApplicationTests.java
@@ -0,0 +1,51 @@
+package cc.cjyx.sc.demo;
+
+import cn.snowheart.dingtalk.robot.starter.client.DingTalkRobotClient;
+import cn.snowheart.dingtalk.robot.starter.entity.DingTalkResponse;
+import cn.snowheart.dingtalk.robot.starter.entity.TextMessage;
+import lombok.extern.slf4j.Slf4j;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+@Slf4j
+class ModbusDemoApplicationTests {
+
+ @Autowired
+ @Qualifier("dingTalkRobotClient")
+ private DingTalkRobotClient client;
+
+
+ @Test
+ void contextLoads() {
+ }
+
+ @Test
+ public void testSendTextMessage() throws InterruptedException {
+// DingTalkResponse response = null;
+
+// response = client.sendTextMessage(new TextMessage("报警通知:构建 TextMessage对象发布!"));
+// Assertions.assertEquals(response.getErrcode().longValue(), 0L);
+// log.info(response.toString());
+// Thread.sleep(3000);
+
+// response = client.sendTextMessage("报警通知:构建普通字符串发布!");
+// Assertions.assertEquals(response.getErrcode().longValue(), 0L);
+// log.info(response.toString());
+// Thread.sleep(3000);
+
+ DingTalkResponse response = client.sendTextMessage("报警通知:通知指定人!", new String[]{"15137603460"});
+ Assertions.assertEquals(response.getErrcode().longValue(), 0L);
+ log.info(response.toString());
+ Thread.sleep(3000);
+
+// response = client.sendTextMessage("报警通知:通知群内所有人!", true);
+// Assertions.assertEquals(response.getErrcode().longValue(), 0L);
+// log.info(response.toString());
+// Thread.sleep(3000);
+ }
+
+}